Behavior confusion

18 views
Skip to first unread message

Cameron Laird

unread,
Jan 15, 2007, 6:49:26 PM1/15/07
to Flapjax
I'm missing something crucial about behaviors.

I don't understand how to format source effectively in Google Groups.
The essence is this:

...
var timerB = timer_b(100);
var formatted = new Date(timerB);
// var formatted = new Date(1168642350194);
...

Briefly, when I load the code above, I see "Invalid Date" on trying to
insertDomB(formatted, ...). If I use a constant value, though, like
the one commented out, everything is happy.

I ask for help.

Leo Meyerovich

unread,
Jan 15, 2007, 8:24:24 PM1/15/07
to fla...@googlegroups.com
Hiya Cameron,

Are you using flapjax as a library or as a language with syntax
support? Your code example suggests the latter. Maybe you could paste
in the full segment?

The following two examples ran through the online compiler for me:

<html>
<head>
<title>Hello world!</title>
</head>
<body>
<p>
The date, {! new Date(timer_b(800)) !}, keeps changing!
</p>
</body>
</html>

<html>
<head>
<title>Hello world!</title>
<script type='text/flapjax'>
var mytimerB = timer_b(800);
</script>
</head>
<body>
The date, {! new Date(mytimerB) ||| clearly cannot have the
description that it !} is alive!
</body>
</html>

- Leo

bernardo

unread,
Jan 15, 2007, 8:40:22 PM1/15/07
to Flapjax
I think the trick is to "lift" to make a new behaviour, maybe like
this:

var timerB = timer_b(100);

var formatted = lift_b(function(t) {
return new Date(t);
},timerB);

insertDomB(formatted,...);

Cameron Laird

unread,
Jan 17, 2007, 3:36:03 PM1/17/07
to Flapjax

Leo Meyerovich wrote:
> Hiya Cameron,
>
> Are you using flapjax as a library or as a language with syntax
> support? Your code example suggests the latter. Maybe you could paste
> in the full segment?
>
> The following two examples ran through the online compiler for me:
>
> <html>
> <head>
> <title>Hello world!</title>
> </head>
> <body>
> <p>
> The date, {! new Date(timer_b(800)) !}, keeps changing!
> </p>
> </body>

Among my confusions: is it feasible to reply through e-mail to
<fla...@googlegroups.com>? I'm now not getting the behavior I expect
that way ...

In any case, I mostly use Flapjax as a library.

I agree that the examples above compile cleanly and give the behavior I
intended to express.

bernardo correctly intuited what I was getting at. Here's an example
of a Flapjax-as-library program whose behavior I can not explain
satisfactorily (wish my whitespace formatting luck):

<html>
<head>
<title>Flapjax Demo: Time 2: JavaScript</title>

<script lang="text/javascript" src="flapjax.js"></script>
<script lang="text/flapjax">

function loader() {
flapjaxInit();

var timerB = timer_b(100);
var x = Date.UTC(timerB);


var formatted = new Date(1168642350194);

// var formatted = new Date(timerB);

insertDomB(timerB, 'timer');
insertDomB(formatted, "formatted_timer");
}

</script>
</head>

<body onload="loader()">
<p>The time in milliseconds is
<span id="timer">not
initialized</span>.</p>
<p>The formatted time is <span id =
"formatted_timer"></span>.</p>

</body>

</html>

Why doesn't "formatted" here become a well-behaved behavior when I
initialize it

var formatted = new Date(timerB);

?

Incidental questions:
A. What's the consequential difference between "text/javascript" and
"text/flapjax"?
B. What's the status of the compiler? I ask because it doesn't appear
under <URL: http://flapjax-lang.org/download/ >. What is *its*
license?

Leo Meyerovich

unread,
Jan 17, 2007, 7:23:13 PM1/17/07
to fla...@googlegroups.com
> is it feasible to reply through e-mail to
<fla...@googlegroups.com>?

Sure, that's how I do it. You should join to post (and for the first
day or two, we must manually OK your messages as a spam preventative).

> Why doesn't "formatted" here become a well-behaved behavior when I
> initialize it
>
> var formatted = new Date(timerB);


Short answer 1: you need to write timerB.transform(function(v) {
return new Date(v); });


Short answer 2: the compiler (flapjax language) would do all of that
automatically for you.


Intermediate answer 1a: we could have overwritten all native functions
to do that specific type of example, and added the requirement that
whenever you define a new function, you 'lift' it. That is slow,
wasteful, and probably breaks many interoperability properties. A
compiler is better suited for this sort of work.


Intermediate answer 1b: functions do not normally take time varying
values, so applying a function to a time varying value is a type
mismatch. For example, think of '+': it is defined on numbers, not
arrays of numbers. However, we may want all functions that work on
numbers to also work on arrays of numbers, returning another array of
numbers instead of a number. For example, [1,2,3] + [1,2,3] = [2,4,6].
What that means is we are changing the semantics of all the operators
(+, -, *, ==, ===). It's easy to do that for user defined functions by
replacing them with functions that check the type of the input, but
some things, like +, cannot be overwritten, and what's more, user
defined functions that exist after everything is transformed..
wouldn't have been transformed. That means the developer has to add a
special case to all their functions they define after flapjax
initializes that work on numbers to also abide by our new array rule.
However, if the developer adds this check to everything, that's an
automatic process, and a compiler can do it. If it's something the
compiler does, that means what is being fed into the compiler is a new
language. Replace the type 'array' in all of the above with
'behaviour' and 'event', and you get flapjax.


Advanced answer 1a: What it boils down to is that while we could make
the flapjax language totally runtime, making all the code you tried
writing work, but the performance and usability would take a hit. This
would require us to include a compiler as part of the client download
and then run everything in a giant eval statement (or even write our
own more convoluted interpreter). The speed, after the load, would
probably be fine, except that initial page load would really hurt,
especially if we threw in all the error support our compiler would
give, and probably trigger a warning. We could actually do both and
let the developer choose, but our type of compilation is better once
you start making large multifile projects, which is the direction RIAs
are headed.


Note: if JavaScript supported macros, we would not have to do run time
interpretation. Brendan Eich, the inventor of JavaScript, was thinking
of adding this to the next version of JavaScript, but seems to have
bailed. I would still make the same speed argument, as the macros
would have to be expanded at page load time.

Furthermore, the amount of manually 'lifting' by a developer is
actually rather minuscule (and an automatic reflex once you work with
the system), and the framework focuses on covering the tougher cases,
such as tagRec and DIVB. Next, we're trying to make real apps
possible, meaning performance (a classical JavaScript concern) must be
good and the 80% case of programs must be expressible. Until a
compiler is mature, it will probably not outperform handwritten code,
and handwritten code is easier to manipulate. The net effect, of local
state instead of global state (aka spaghetti code), and forwards
execution (functions / transformations) instead of backwards execution
(callbacks) is still dominant, with the latter being even more
prominent because of explicit calls to lift and transform. As the
lifting is manually controlled, there is a lot of room for developer
optimization (as mentioned and utilized by Noel in an earlier post in
this thread).

Advanced answer 1b:

I can reference over a decade of research papers directly relevent to
Flapjax style programs, and several more related to the particular
question of why some things are done through a compiler instead of
'just working in javascript', so feel free to ask some more! I have a
feeling a lot of your questions are just from learning a new way of
coding, similar to the first time you use first class functions (used
to specify callbacks for the 'a' in ajax).


> Incidental questions:
> A. What's the consequential difference between "text/javascript" and
> "text/flapjax"?

Flapjax code compiles into javascript code. Browsers aren't equipped
with flapjax compilers, but do have javascript ones, so anything in a
text/flapjax tag is compiled into a text/javascript tag before a page
is sent to a browser.


> B. What's the status of the compiler? I ask because it doesn't appear
> under <URL: http://flapjax-lang.org/download/ >. What is *its*
> license?

Most of the fixes posted on the newsgroup are actually related to the
compiler, so the status is 'active' and 'gaining features'. No license
needed right now because we're offering it as a free unlimited
webservice (same as our server itself), easing the maintenance burden.
We welcome any interest in it - a Berkeley professor is even toying
with the idea of making a stripped down version of it an assignment
for one of his courses!


Hope that helped!

- Leo

Michael Greenberg

unread,
Jan 18, 2007, 12:42:33 PM1/18/07
to Flapjax
There's not a lot to add to Leo's excellent, parfait-layered answer,
but...

> > B. What's the status of the compiler? I ask because it doesn't appear
> > under <URL:http://flapjax-lang.org/download/>. What is *its*
> > license?

...the code for the compiler itself is unreleased -- this makes it
easier for us to make bug fixes and is also in the spirit of a web
programming language. The fxc program,
<http://www.flapjax-lang.org/compiler/fxc>, is under the BSD license,
with some included third-party code (also under the BSD license).

Michael

Cameron Laird

unread,
Jan 19, 2007, 3:26:26 PM1/19/07
to Flapjax

On Jan 17, 6:23 pm, "Leo Meyerovich" <lmeye...@gmail.com> wrote:
...


> > Why doesn't "formatted" here become a well-behaved behavior when I
> > initialize it

...


> Intermediate answer 1b: functions do not normally take time varying
> values, so applying a function to a time varying value is a type
> mismatch. For example, think of '+': it is defined on numbers, not

...
You gave me much explanation, and I appreciate all of it; it's
valuable. I recognize that I have no background in FRP, so learning
what has been found productive and useful is indeed much of what I'm
after.

"[F]unctions do not normally take time-varying values ..." still floors
me. I just don't know what to make of that, as it's so different from
my background. It's sure worth discussing, though, because, once I
assume it, your remark about type conflict is potent. I suspect this
shows how far I have to go to "get" FRP.

I earlier complained about the tutorial's promise that "if an
expression is a behavior, all expressions whose values depend on it
also become behaviors." In terms of a formalization like <URL:
http://www.mozilla.org/js/language/js20/formal/parser-grammar.html >,
through which expressions does Flapjax propagate behavior? Is it
UnaryExpression?

In casual conversation, is it fair to say that an "arithmetic
expression" which embeds a behavior is itself a behavior?

Michael Greenberg

unread,
Jan 19, 2007, 9:12:28 PM1/19/07
to Flapjax
On Jan 19, 3:26 pm, "Cameron Laird" <cla...@phaseit.net> wrote:
> "[F]unctions do not normally take time-varying values ..." still floors
> me. I just don't know what to make of that, as it's so different from
> my background. It's sure worth discussing, though, because, once I
> assume it, your remark about type conflict is potent. I suspect this
> shows how far I have to go to "get" FRP.
>
> I earlier complained about the tutorial's promise that "if an
> expression is a behavior, all expressions whose values depend on it
> also become behaviors."

I think the fundamental problem here is a confusion between the
tutorial, which uses the Flapjax compiled language, and the code you've
listed above, which uses Flapjax as a library. These two modes --
language and library -- require different programming styles.

The first question we need to ask is: what is a behavior? Each mode
has its own answer.

Language: a behavior is a value which changes over time. For example
timer_b(100) is the number of milliseconds since the Epoch, changing
every 100 milliseconds. Expressions like timer_b(100) + 5 and
timer_b(100) / 1000 will result in new values that update over time.
We can show that it varies over time with calls to functions like
insertDomB and the in-line templating syntax.

Library: a behavior is an object managed by flapjax.js. The library
offers ways to manipulate this value, primarily by means of 'lift's and
'transform's. For example, timer_b(100).transform(function (v) {
return v + 5; }) is behaviorally (sorry) equivalent to the expression
timer_b(100) + 5 -- _in_the_Flapjax_language_. Note that if we write
timer_b(100) + 5 when we're using the Flapjax library in plain
JavaScript, we get a type error, just like if we said { foo: 'is an
object' } + 5. The Flapjax library offers insertDomB, just like the
language, so there's a way to use the computations specified by the
chains of managed objects (behaviors) we build.

> In terms of a formalization like <URL:http://www.mozilla.org/js/language/js20/formal/parser-grammar.html>,
> through which expressions does Flapjax propagate behavior? Is it
> UnaryExpression?

On cursory inspection, it seems like the Flapjax language will
propagate behavior through every NonAssignmentExpression. Putting it
in English, we get the surprisingly similar-sounding edict that the
Flapjax language supports behavior propagation up to mutation (++ and
friends) and state (some uses of =, [], for, if, while). In fact, the
Flapjax compiler will signal an error when it detects some of these
(++, for, if, while).

> In casual conversation, is it fair to say that an "arithmetic
> expression" which embeds a behavior is itself a behavior?

Language: Yes, but 'embed' is awfully fancy for my sort of casual
conversation. ;)

Library: No, since objects don't belong in arithmetic expressions.

Cheers,
Michael

Leo Meyerovich

unread,
Jan 19, 2007, 9:55:47 PM1/19/07
to fla...@googlegroups.com
> You gave me much explanation, and I appreciate all of it; it's
> valuable. I recognize that I have no background in FRP, so learning
> what has been found productive and useful is indeed much of what I'm
> after.
>

I want to preface this with saying I'm differentiating between the
language mode (meaning using the compiler) and library mode (meaning
writing standard javascript without the compiler). Also, I think you
took a good approach to write a few functions and experiment. I saw a
tutorial elsewhere that took a similar approach, which helped me a lot
- maybe we should do that too, and include mini-REPLS and testsuites
for each problem. 'FRP' is just an acronym - we can describe
javascript as a LALR(1) dynamic language with hoisting on its first
class functions (and do), but people's preference for it as a
scripting language doesn't change! Flapjax uses concepts from
elsewhere that many of us use every day. The trick is learning those
concepts for the first time and recognizing them in the context of
javascript.


> "[F]unctions do not normally take time-varying values ..." still floors
> me. I just don't know what to make of that, as it's so different from
> my background. It's sure worth discussing, though, because, once I
> assume it, your remark about type conflict is potent. I suspect this
> shows how far I have to go to "get" FRP.

The difference between the relationship of time varying values with
normal values, versus that of arrays of values with normal values
exists in terms of habits between converting values, so my comparison
was a little unfair, but your final questions jumps right at what is
going on. The comparison was just to get you started and provides an
easy sanity check.

A function, like say add1 'var add1 = function (x) {return x +1;}; ',
is defined to work on a single value. However, if you have a stream of
numbers and the add1 function, you have a javascript type mismatch if
you normally just write 'var myIncrementedStream =
add1(numberStream);'. Actually, you couldn't really do that at all -
javascript doesn't have the notion of streams; the closest it has is
arrays. We added our implementation of event streams and convenient
ways of manipulating and combining them, so 'var myIncrementedStreamE
= numberStreamE.transform_e(add1);' is valid javascript. Your last
question (I'm getting there!) gets at the idea that working with
streams follows some simple patterns and that we can probably cut down
on all the necessary calls to things like ''transform'. In the
language, we just write 'var myIncrementedStreamE =
add1(numberStreamE)' as we'll see that the compiler knows how to add
the transform to the outputted javascript.

If you've had the chance to do shell programming, you'll notice a
close conceptual similarity. A stream of events are 'piped' into other
functions, potentially stateful ones, creating new ones. In a shell,
you mainly get '|', '>', '>>' and a few others to put together your
powerful C programs, while we give a lot more and the ability to make
new ones in javascript. A shellscript interpreter takes care of all
the calls related to composing called programs together and
propagating events with a nice syntax, similar to the flapjax language
mode. Just like our compiler, the shell script interpreter takes care
of the same type mismatch behind the scenes, instead of making the
programmer do the quick conversion. The library mode is great because
of how easy it is to do both this style of event code and traditional
javascript - and web apps need both!

>
> I earlier complained about the tutorial's promise that "if an
> expression is a behavior, all expressions whose values depend on it
> also become behaviors." In terms of a formalization like <URL:
> http://www.mozilla.org/js/language/js20/formal/parser-grammar.html >,
> through which expressions does Flapjax propagate behavior? Is it
> UnaryExpression?
>

I want to say NonAssignmentExpression, though JavaScript's syntax
breakdown is notorious. Basically, whenever you have a value, then a
transformation to yield another value (function application like my
add1 example, logical connectives or arithmetic, etc), transforming
that first value with a time varying one means the transformed value
will also be time varying. This is where our javascript function name
'transform' comes from. Lift has an even more compelling reason, but I
won't bore you with that.

> In casual conversation, is it fair to say that an "arithmetic
> expression" which embeds a behavior is itself a behavior?
>

In flapjax, yep. In javascript, you have a type mismatch, similar to
adding two arrays. Functions make it a little more interesting in two
ways.

First, a value might actually be a function, suggesting which function
you're applying also changes over time!

Second, in terms of your fairness question, Mike might have something
to say about side effects like value assignment expressions within
bodies of functions behaving oddly. This is mostly because you'd be
hard pressed to come up with a global, consistent explanation of how
they should behave - you can't do it in shell scripts either.

Constant_b takes a normal value and makes it a time varying one. Lift
takes a mixture of time varying and normal values, the first one
either a function or a time varying function, and returns a time
varying value: the time varying function application. That's the
essence of introducing and then manipulating time varying values, with
analogues for events. If you think about it, constant_b can even be
defined in terms of lift_b with an identity function! A similar story
exists about getting normal values back (insertValue, valueNow).

Everything else is about convenient forms of expression. Once you're
comfortable with lift, the rest is about building up abstractions even
more tuned to what you are doing, like our DOM constructs, persistent
data bindings, and compiler that inserts calls to lift. As you noted,
if we can syntactically isolate values and their manipulations (or the
introduction of time varying values and their subsequent
manipulations), we can insert the calls to lift/transform
automatically, and thus transparently manipulate time varying values
in our flapjax code.

Ok, off to watch another Kar Wai Wong film :) I'm betting Mike will
have a more concise explanation that nails the necessary parts
clearly.

- Leo

[PS: Mike, how was that for a description of Warm Fuzzy Things? I
think I may have gone overboard.]

Cameron Laird

unread,
Jan 20, 2007, 4:08:55 PM1/20/07
to Flapjax
On Jan 19, 8:55 pm, "Leo Meyerovich" <lmeye...@gmail.com> wrote:
...
> took a good approach to write a few functions and experiment. I saw a
> tutorial elsewhere that took a similar approach, which helped me a lot
> - maybe we should do that too, and include mini-REPLS and testsuites
> for each problem. 'FRP' is just an acronym - we can describe
...
Test suites--ALWAYS welcome.

You "saw a tutorial elsewhere ..."--was that a tutorial on Flapjax?
I'd like such a reference for my records.

Leo Meyerovich

unread,
Jan 20, 2007, 4:30:39 PM1/20/07
to fla...@googlegroups.com
> ...
> Test suites--ALWAYS welcome.
>
> You "saw a tutorial elsewhere ..."--was that a tutorial on Flapjax?
> I'd like such a reference for my records.
>

Nah sorry, on haskell monads, AKA Warm Fuzzy Things.

The REPL widget sounds kind of nifty actually, as it should support
both library mode (exception handling evaluation within the current
page) and compiler mode (as a webservice, maybe evaluating in an
iframe). We talked about a basic version earlier, and incorporation in
tutorials finally motives doing one, and doing it well.

- Leo

Shriram Krishnamurthi

unread,
Jan 20, 2007, 6:22:25 PM1/20/07
to fla...@googlegroups.com
Cameron --

> You "saw a tutorial elsewhere ..."--was that a tutorial on Flapjax?
> I'd like such a reference for my records.

You are aware of

http://www.flapjax-lang.org/tutorial/

right?

Shriram

Cameron Laird

unread,
Jan 20, 2007, 9:04:20 PM1/20/07
to Flapjax

On Jan 20, 5:22 pm, "Shriram Krishnamurthi" <s...@cs.brown.edu> wrote:
> Cameron --
>
> > You "saw a tutorial elsewhere ..."--was that a tutorial on Flapjax?

> > I'd like such a reference for my records.You are aware of
>
> http://www.flapjax-lang.org/tutorial/
>
> right?
...
Yes.

I certainly have been aware of it. I gather the tutorial remains on
the list for revision ... In any case, yes, thank you for the explicit
reference; if I weren't already aware of it, I certainly would want to
know.

Although my question wasn't clear, Leo answered it fully; his mention
had in mind the well-known tutorial on Haskell monads.

I'm myself working on a tutorial complementary to the standard one:
it'll assume less background of readers, and that their primary
motivation is application development (as opposed to language theory,
...). I hope to publish it in February.

Shriram Krishnamurthi

unread,
Jan 21, 2007, 3:30:07 AM1/21/07
to fla...@googlegroups.com
Sounds great. We'd be happy to provide feedback if you want it
before you publish it.

Shriram

Reply all
Reply to author
Forward
0 new messages