Pliant talk forum

Pliant talk forum

Discussion: Making pliant comfortable

Why can't pliant be as easy as javascript, perl or ruby
for working with arrays and hashes, and loops ? What about
automatically managing section rewrites, and having events
and listeners. Breaking up code into reusable components ?
Message posted by maybe Boris Reitman on 2008/07/07 12:11:40
There's something to be said about making Pliant comfortable.
The whole UI design is great, but it is very raw. It really defines a protocol, 
like a CGI in terms of sections, replays and rewrites, and input constructs.
There needs to be a framework on top of that to allow:

- easy way to group transient data
- easy way to break-down ui functionality into reusable components,
  (I don't mean presentation from logic. That is solved reasonably well for 
  html by the template construct.)
  What I mean is if I have a form consisting of very common parts, 
  I'd like to factor it out. Or if I have a lot of different boxes 
  on the website, I'd like to code each in an isolated fashion, 
  but also be aware about the overall context.

I think it would be good (I mentioned this earlier) to declare ui_methods rather 
than ui_functions, so that it would be possible to store state for a request.

I don't understand why pliant ui code looks like a very very long sheet 
of paper. Is this really what happens when you write GUI code ?

I would also benefit from a macro "for" loop, like this. 
Say I want to do the same thing to 4 different objects, 
I'd like to be able to say:

template get_resource:"someform"
  for field (firstname lastname username password)
    template_section field:ident
      input "" field
    template_section field:ident+"_error"
      input "" (new Ident field:ident+"_error")

Basically, what I am trying to say is that I'd like break down form 
handling into:
- declaration of fields to be filled in
- error handling of the fields
- and event handling (when some button is pressed)

The ability to group fields of input into a type is a first step in this direction,
because I can create a type called UserCredentials with username, email, password,
email_retype, and password_retype which will be displayed by one ui_function,
validated by another ui_function, and registered into the system by another ui_function.
I will also need to create a very boring function called init:

credentials firstname :> new Str
credentials lastname :> new Str
credentials username :> new Str
etc for all fields. Thats where a "for" loop like above would come in handy.
For example, in perl this is not an issue:
for $var ( keys %$self ) {

I have been working with Flex and MXML. Here's how they did the GUI layer.
It is like html, but implementation for every tag is declared in a class.
Attributes have configuration parameters. If attribute values is enclosed in {}
like <Label text="{form.firstname + " " + form.lastname}"/> then 
the change in form's firstname and lastname will be automatically propagated
to the label.

So in this system "sections" are replayed automatically, and not explicitely.
There's a hidden layer of observer that get updated 
when observed data changes.  Maybe pliant ui needs something similar.

In general, I really like pliant for the overall design, but I find throwing something 
quick in perl still easier.  Arrays and hashes are easier to work with.
For example $a{a}{b}{c}{d} is automatically created as a multilevel hash/dictionary.
Or,  for my $a (sort{} map { ... } grep { ... } (@data)) {} 
I don't understand why pliant can't have arrays and hashes for dumb people,
just as easy as perl, or javascript where everything is automatic.

Also, I don't understand why there is no easy way to create an anonymous 
closure (delayed action),

var Function func := function x y z -> w

Also, I keep most code in the same .ui file.  If I break the code into two 
separate ui files, is the included ui file always recompiled like the main one ?
Message posted by maybe Hubert Tonneau on 2008/07/07 14:23:02
You are raising a lot of questions at once, so I'm afraid I might not be abble
to properly answer all of them in a reasonable amount of lines.

. You have a problem because you want to code the client state as a single
  structure in order to pass it easierly to various functions (and it makes
  sense for many applications) but input does not work for non object fields

  We can just modify the input meta programming code in order to store
  object + field offset + field type instead of just object (see UIServerVariable
  data type) so that a field of an object be accepted.

. You would like methods instead of functions

  Functions and methods are exactly the same in Pliant (there is no 'Method'
  data type). The only method related special thing in Pliant is that the first
  argument is special because it's used for 'generic'. This does not apply
  to user interface code, so I see no problem here.

. You would like to separate the semantic from the rendering in the user

  Also, it's a at first good looking idea, I look at it more and more as a
  Pandora box. Separation should be styling (CSS or Pliant styling).
  Well, it work for very basic things, but for more advanced, more complex
  changes have to be applied so that generating a different set of rendering
  tags is necessary.
  Well, it works a bit better, but for even more complex things, it is
  necessary to scan the all page to decide the changes, so that sending the
  content to the browser on the fly is not possible any more (with serious
  scalability related issues)
  Well, it works even better, but for even more complex things, writing the
  code differently is required because we don't know how to do it
  automatically (as an example, some information is missing).

  So, Pliant UI went the easy way: we provide entry level CSS like styling
  with a very efficient (so constrained) implementation.
  We could make all tags generic at some point, but dynamically changing the
  binding prooved to be not that valuable.

  On the other hand, I plan to add at some point a third party rendering
  tag notion. I mean the server says tag 'foo' can be rendered by server
  at URL xxx. Then the client is free to ask the specified server for
  rendering, or one that is closer (connected through faster bandwidth)
  but known to provide the same capability.
  Also, a lot of details have to be defined about what information the
  UI client has to send to the rendering server (probably the subtree plus
  the parent nodes) and how the rendering server sends rendering informations
  So, don't expect anything in this area on the short run since my main task
  is documenting the existing.

. You would like so shortcuts in code writing (func := function x y z -> w ..)

  This is just a question of writing the meta programming rules.
  The current ones expose my personal taste, but Pliant compiling engine has
  room for much more. The problem is will it make programs easier to maintain.
  First, writing tricks tend to favor the program writer at the expense of the
  reader. Then, Pliant is so flexible, that people that learned one way of
  writing Pliant programs could have hard time to read programs that use
  a lot of meta programming and syntax level extensions.
Message posted by maybe Boris Reitman on 2008/07/07 16:15:33
> . You have a problem because you want to code the client state as a single
>  structure in order to pass it easierly to various functions (and it makes
>  sense for many applications) but input does not work for non object fields

>  We can just modify the input meta programming code in order to store
>  object + field offset + field type instead of just object (see UIServerVariable
>  data type) so that a field of an object be accepted.

ok, I will give it a shot.

> . You would like methods instead of functions
>  Functions and methods are exactly the same in Pliant (there is no 'Method'
>  data type). The only method related special thing in Pliant is that the first
>  argument is special because it's used for 'generic'. This does not apply
>  to user interface code, so I see no problem here.

The cool thing about methods is that I can use "implicit" to never 
mention this extra state argument. At the moment, ui_function is actually
a method on the UI context object, so (input is actually context input).
It would be better if the state was passed automatically around, without having
the programmer worry about it too much.

>. You would like to separate the semantic from the rendering in the user
>  interface.
>  Also, it's a at first good looking idea, I look at it more and more as a
>  Pandora box. Separation should be styling (CSS or Pliant styling).

No, you misunderstand me. I do not mean styling or positioning of fields.
I mean just listing the required fields (the input "" X) fields and the data.
I just mean that even listing them should have the opportunity of 
factoring the code.  Because on even a "Sign-up" form I have quite a few fields,
username, email, email_retype, password, password_retype.  At the moment, this
can be factored at ui_function level -- the ui_function itself encodes the complete
interface -- too long.  

Here is a concrete example. I have three forms:
"write a new post", "reply to a post" and "login/signup".  I want the user
to start writing or replying to the post. If he is not logged I will show
him the login form embedded in the main form.  When the button "submit post"
is pressed, I want the handler for the button to also invoke the code to handle 
the login (the login form when embedded will not have its own "login" button).
I think with the ability to group fields into one datatype I can solve this reasonable,
by creating three ui_functions: display_login_form, validate_login_form, and register_user
which will all receive the same set of fields grouped in the UserCredentials datatype.

I mean that something like this will appear often, so we must think of the best
way to handle this.

Message posted by maybe Boris Reitman on 2008/07/07 16:16:00
>. You would like so shortcuts in code writing (func := function x y z -> w ..)
>  First, writing tricks tend to favor the program writer at the expense of the
>  reader. Then, Pliant is so flexible, that people that learned one way of

There seem to be a culmination of standard tricks in several popular languages,
such as javascirpt/actionscript, perl, and ruby in which the most common 
operations are dumb-simple.

- callbacks are created very easily sub() { ... }
- special notation quickly creates an array:
  perl: (a,b,c)  ruby: same, javascript: new Array(a,b,c)
- hashes are created on demand:  a['newkey'] = 1 automatically creates 'newkey'.
- simple way to iterate over keys and values
  for (k in array-or-hash) { ... }
  for each (v in array-or-hash) { ... }

So given all the power of pliant, why not create a module called easy.pli
that brings pliant to the layer of abstraction of most common and 
popular languages. That *would* make the code more readable simply because
the readers have that kind of background. Currently pliant addresses
the C++ programmers -- the people that are prepared to get messy to get 
anything done. However, most people today are not prepared to get messy for 
small little programs.

For example, why 'eparse' crashes on empty string ? 
Why can't it just not match ?  Why isn't there standard string operations 
such as split() ? Why is there no way to match 0-or-more (the *). 'any' consturt
is like a '+', it must match something. Why is there no "contains"
to check if a string appears inside another ? its a very common operation,
and doing (x search y -1)<>-1 is not very readable to anyone but C programmers.
How do I catch returned output from execute() command ? (the backticks). 

These are the kind of small things here and there that I mean, but they ad-up.
Why not create a good mix of cool features and throw it into one or two 
easy modules.

- another thing I really want is to be able to overwrite / execute any method in 
  any module, not even exported ones.  This is really good for testing.
  I can do this in perl. MyPackage:my_function() -- i call it, or 
  MyPackage:my_function = sub { new code }. The new code replaces the implementation
  of the function for everyone, including callers from inside MyPackage module.
  I don't see why thihs is not possible - the entry in pliant symbol table 
  needs to be found somehow and new code installed there.  Maybe, this is not 
  even needed in live mode, only in debug-testing mode.

  The reason is that often I write a module with only one exported function,
  but there are many small functions that a private. However, from within my test,
  I would like to execute every single one of them, just to see thaht it works.
  This is called "testing oriented" programming, with a fancy name Extreme Programming.
  Fancy or not, it's a great way to program because it allows to build complex code in
  small steps each of which is simple.

- can we have a construct that brings extra syntax to a block of code, or part of code?
For example,

import module "/pliant/fancy_feature.pli";
# code inside uses fancy feature.
unimport module "/pliant/fancy_feature.pli"
# fancy feauter here is a syntax error.

So to conclude, in my opinion it is great that pliant provides extensions engine.
Only, now basic extensions should be created on top of it to match in features & easy 
of use any mainstream programming language.  Those who don't want such features,
don't need to include those modules.

Many people who I spoke to said that pliant syntax is intimidating. 
Can there be a module that changes the syntax to standard {} 
one for blocks with no indentation constraints ?
Also, functions could be written in standard form as f(arg1,arg2) and have 
the compiler convert it automatically to (f arg1 arg2) before they are fed off to meta functions.  
I personally prefer the pliant syntax. But if I pliant can have a drop-in module
that makes it use javascript-like syntax, then why not have it, to address those
many users who already know javascript?
Message posted by maybe Hubert Tonneau on 2008/07/08 10:54:23
> callbacks are created very easily sub() { ... }

Pliant is even better in this area: you don't have to write anything special.
When you use 'button' instruction or 'sort' option in an 'each' instruction,
the underlying code or paramater is a callback function, but it's just
silently created thanks to meta programming.

> special notation quickly creates an array:
  perl: (a,b,c)  ruby: same, javascript: new Array(a,b,c)

It does not fit nicely with Pliant syntax (unless somebody finds a solution
that I have not found).
If the array just 3 elements, we want to provide it on a single line.
If it's 100 elements, we want to provide it on several lines.
Pliant automatic mapping of indentation to {} will make having a clean
notation hard.

I think that a nice notation to provide a structure would be more interesting:
type Foo
  field Int a b c d
var Foo f := foo 10 20 30 40
var Foo f := foo 10 20 d<-40
The problem is with the last line: we need a sign to enable to provide the data
structure with only a subset of the fields, the right one would be ':', but
we cannot use it because it's already assigned to avoiding parentheses.

> hashes are created on demand:  a['newkey'] = 1 automatically creates 'newkey'.

Well, it does exists, but I did not remember, so I don't use it.
var (Dictionary Int Int) a
a ¨newkey¨ := 1 # crashes if the key does not exists
a ¨newkey¨ 0 := 1 # automatically creates 'newkey' with value 0 if it does not exists.

> simple way to iterate over keys and values
> for (k in array-or-hash) { ... }
> for each (v in array-or-hash) { ... }

Alread exists: it is 'each' instruction.
Message posted by maybe Boris Reitman on 2008/07/13 09:09:55
Alright, I would like to be able to pass callbacks to a function.

For example,

ui_fuction display_complex_widget title ok_handler cancel_handler
  arg Callback ok_handler cancel_handler ; arg Str title
  text title ; eol
  button "ok"

  button "cancel"

then, to use

  display_complex_widget "hello"
      section_replay "..."

We are coming back to the discussion that if we are going to keep the basic
pliant syntax with identations, we need to allow to specify arguments 
in key=>value fashion.

Here is why I would need something like this: it allows to completely
isolate the widget. In a way the widget becomes a sort of "button" with a handler
below it.

The current system is very good for buttons, but doesn't allow to easily create 
complex widgets on top of it.
Message posted by maybe Hubert Tonneau on 2008/07/13 11:28:19
There is no problem to do it: you just need to do a little bit of meta

I very fiew words, 'display_complex_widget' meta will build the various call
back functions using 'freeze' meta programing feature, then call a standard
function and pass the callback functions as parameters.
Your 'Callback' data type is in facts 'DelayedAction' existing data type
automatically built by 'freeze'.

See 'hook' usage in /pliant/graphic/ui/sample/test.ui
and implementation in /pliant/graphic/ui/server/api.pli
Also 'hook' records each callback one after the other instead of calling a
single function with all callbacks provided as arguments.
Message posted by maybe Boris Reitman on 2008/07/13 12:10:09
I know about all that, as I have done it with the template construct.
Writing meta functions is a complicated thing -- I'd like this feature to be 
available for any function or ui_function. I think function argument handling
needs to be extended to support it. 

I want two things:
1. ability to specify function argument as key-value rather than in sequence
2. ability to form a callback easily

function func1 x -> y
  arg Int x y

function myfunc a b callback
  arg Str a b ; arg prototype:func1 callback
  callback execute 5

and to call,

z := "hello world"
myfunc "hi"
  b "bye"
  callback x -> y
    arg Int x y
    y := x + x
    console z eol

I have a lot of ui_functions each encoding sub-ui components, 
and I'd like to make them more independent, because now they are all 
aware of their context. This warps the code in a bad way.

The trouble with DelayedAction is that it is too low level.
In order to execute it I need to provide context.

 function execute1 a f
  arg Address a ; arg Function f
 execute1 da:parameter da:function

It is too verbose, there needs to be an easier way to call it.
Also, DelayedAction is not quite a closure/callback, because callback can 
receive more arguments.  Sometimes it can be very useful.

These kind of features are available in all popular languages today, 
including javascript.
Message posted by maybe Hubert Tonneau on 2008/07/13 14:25:36
Your get back to question standing from the beginning of Pliant:
we want 80% of meta programming capabilities, but without the complexity.
The problem I see with it is that the answer seems to depend what kind of
programs you are writing. I mean, there don't seem to be a single answer,
but somebody could proove me wrong in the futur.

The big problem with a general callback function is that the parameters
comme from both environments: some from the caller function, some from the
called function.

Here is an example:

var CBool case_sensitive
var (Data Set:Str) dict # a dictionary of words
each w dict sort (shunt case_sensitive w lower:w)

How do you turn (shunt case_sensitive w lower:w) to a callback function ?
Basically, it receives the 'w' parameter from the called 'each' function,
but it also receives the 'case_sensitive' parameter from the function
calling 'each'.
Popular languages, as you say it, provide no solution, except C that will add
a (void *) parameter to the callback function that will be used to feed the
caller parameters.
This is what Pliant handles sometime with DelayeAction, sometime through
turning the called function to an inline sequence.

Now, about syntax, just in case you would not be awared of it.
If you have:

function foo x y f
  arg Int x y ; arg Function f

Then you can call it through:

foo 1 2 (function callback x -> y { arg Int x y ; y := 2*x })

Anyway, the prototype of the function will not be checked at compile time.
Message posted by maybe Boris Reitman on 2008/07/13 15:16:19
>var CBool case_sensitive
>var (Data Set:Str) dict # a dictionary of words
>each w dict sort (shunt case_sensitive w lower:w)
>  ...

sure, it works in javascript, or actionscript, or perl:

var case_sensitive=1;
setTimeout(function() { alert('case_sensitive:'+case_sensitive) });

or in perl:

sub pretty_print {
  my $char = shift;
  my $closure = shift;
  print &$closure($a); 

my $case_sensitive = 1;
pretty_print("hello world", sub { 
  my $char = shift; 
  return $case_sensitive? uc($char) : $char; 

> foo 1 2 (function callback x -> y { arg Int x y ; y := 2*x })

thanks, I knew that, but it is impractical for real-world fuctions 
that span several lines, and use longer names for variables.
As well, these are functions, not closures.

>Popular languages, as you say it, provide no solution, except C that will add
>a (void *) parameter to the callback function that will be used to feed the
>caller parameters.

When you started to work on pliant C/C++ was the dominating language, and you 
used it as the base-comparison.  And it is great, because Pliant is as fast 
as C. But compared to scripting languages, pliant solutions to common problem 
of passing pieces of code around (as well as data-scructures) is very awkward 
and too low-level. The "hook" and "button" handlers are perfect, but 
the moment someone tries to step outside these given tools, one has to dive deep
into meta programming.

(For example, about datastructures: doing polymorphism on Data:* datatypes, 
which are basic building blocks of any pliant application is difficult, 
because "maybe" doesn't work for them.)

So my opinion stands -- there needs to be an easy way to declare an inline 
closure function that will receive arguments from both the context environment, 
and from the call.

As a matter of fact, all the time-tested features available in other languages
should be added to pliant in form of modules.  Passing arguments in key-value form
was available in perl for a while, but now it is in javascript and actionscript, 
and ruby too. 
Message posted by maybe Hubert Tonneau on 2008/07/13 16:16:16
> sure, it works in javascript, or actionscript, or perl:
> var case_sensitive=1;
> setTimeout(function() { alert('case_sensitive:'+case_sensitive) });

This is a global variable, not a variable passed from the caller environment !

> When you started to work on pliant C/C++ was the dominating language, and you 
> used it as the base-comparison.

No. It did not append that way.
My target was: a single language for everything.
The best answer, previous to Pliant, used to be C++.
Message posted by maybe Boris Reitman on 2008/07/13 18:19:39
This is working code, try it.  You can just paste it into firebug console:

function testme() {
  var case_sensitive=1;
  setTimeout(function() { alert('case_sensitive:'+case_sensitive) }, 1000);
Message posted by maybe Hubert Tonneau on 2008/07/13 18:49:39
You are right.

Please try:
function changeit() { c = 3 } function testme() { var c = 1 ; setTimeout( function() { alert('c = '+c) }, 1000) ; c = 2 ;  changeit() } testme()
function changeit(c) { c = 3 } function testme() { var c = 1 ; setTimeout( function() { alert('c = '+c) }, 1000) ; c = 2 ;  changeit(c) } testme()
What is the underlying semantic ?
Message posted by maybe Boris Reitman on 2008/07/13 20:05:31
> Please try:
> function changeit() { c = 3 } function testme() { var c = 1 ; setTimeout( function() { alert('c = '+c) }, 1000) ; c = 2 ;  changeit() } testme()
> then:
> function changeit(c) { c = 3 } function testme() { var c = 1 ; setTimeout( function() { alert('c = '+c) }, 1000) ; c = 2 ;  changeit(c) } testme()
> What is the underlying semantic ?

so what is the mistery ? 
in the first case changeit() is bound to a global 'c', 
because lexicaly it is looking at c at global scope. 
Once that binding is made, it never changes,
and is encoded into parsed form of the function. So you can't expect it to 
modify c declared inside testme() with a var. 

In the second case, changeit() never actually changes anything,
because c is not passed by reference (it is not arg_rw) but is passed as a copy. 
the fact that the function receives a formal argument c, means that it will not 
use the global c in its declaration.

Now, in perl there are two types of declarations "my" and "local".
Here are working examples:


sub changeit { $c = 3 }

sub run {
  my $callback = shift;

sub testme() {
  local $c = 1 ;
  my $callback = sub { print ('c = '+$c) };
  $c = 2;

testme() # prints 3

If you change declaration 'local $c' to 'my $c' then the output will be 2.

In the "dragon" compiler book it is called lexical vs. dynamic binding.
In javascript binding is lexical only, but perl supports both.
Message posted by maybe Hubert Tonneau on 2008/07/14 00:04:40
> so what is the mistery ? 

I thought my second sample output was 3, because I got 3 when experimenting,
but my test code probably contained a typo error that made me conclude wrong.