From 7f52e24dfe474d0c9958f7a7b782abde4ef9b8a5 Mon Sep 17 00:00:00 2001
From: snowmantw Fluorine is a Javascript library and eDSL, want to help developers constructing their
+application with more functional features, and build large programs from small functions.
+It currently has these features: It's first inspired by the Arrowlets library,
+which brought functional structure, the Arrowlet, into Javascript world. Of course, the great jQuery
+and Underscore.js also shown how amazingly Javascript could be. Futhurmore, this library also want to experiment the possibility of constructing reasonable Javascript programs
+without (too much) class, object and other OOP things. Because Javascript, at least according to Douglas Crockford,
+"has more in common with functional languages like Lisp or Scheme than with C or Java".
+This is a good point in this age of OOP-mainstreaming, especailly most of libraries are all eager to provide class, inheritance and other OOP stuffs. Fluorine can help Javascript programmers isolate impure parts in their applications,
+so that errors resulted from side-effects can be reduced as much as possible: Programmers can still mix them in some proper ways, like in a generator function
+returing yet another larger context: Basically, pure functions and values now can't arbitrarily mix with impure things: But in some special cases, we can still do that if the context come with some extractor functions: Also, we can do some dirty things in the theoretically pure combinator, like the This is sometime useful because we may want to embedded 3rd libraries in our contexts. Nevertheless, these tricks should be exceptions, not normalities. Fluorine is a Javascript library and eDSL, want to help developers constructing their
+Fluorine: a context based Javascript library
+
+
+
+
+Features
+
+Isolate Impure Parts in Javascript Applications
+
+
+
+fluorine.infect()
+
+// Impure function: directly manipulate DOMs in the document.
+// All impure computing should be wrapped with contexts.
+//
+// :: String -> UI ()
+drawMyName = function(name)
+{
+ return UI('#name-user').$().text(name).done()
+}
+
+// Pure function: return a plain old string.
+//
+// :: String
+giveName = function()
+{
+ return "foobar"
+}
+
+
+// :: UI ()
+drawApp = function()
+{
+ return UI().
+ let(giveName).as('name').
+ tie( function()
+ {
+ // Use them just like "let" in other languages.
+ var slc_ex1 = '#ex1'
+ return UI("<div id='name-user'></div>").$().appendTo('#ex1').done()
+ }).
+ tie( function()
+ {
+ // Fetch the value pre-defined by `let` and `as`.
+ return drawMyName(this.name)
+ }).
+ done()
+}
+
Break the Glass in Emergency
+
+
+
+// :: String
+pureString = function()
+{
+ return "pure"
+}
+
+// :: UI String
+impureString = function()
+{
+ return UI("impure").done()
+}
+
+illegal_string = pureString() + impureString() // Error.
+
+
+illegal_string = pureString() + impureString()().extract() // UI String -> String
+
let
or _
:
+
+UI('#name-user').$().
+ _(function(e)
+ {
+ // Should keep pure, not violent that like this:
+
+ $(e).text("name changed !")
+ }).
+ done()
+
Fluorine: a context based Javascript library
+
+
+
It's first inspired by the Arrowlets library, -which brought functional structure, the Arrowlet, into Javascript world. Of course, the great jQuery -and Underscore.js also shown how amazingly Javascript could be.
- -Futhurmore, this library also want to experiment the possibility of constructing reasonable Javascript programs -without (too much) class, object and other OOP things. Because Javascript, at least according to Douglas Crockford, -"has more in common with functional languages like Lisp or Scheme than with C or Java". -This is a good point in this age of OOP-mainstreaming, especailly most of libraries are all eager to provide class, inheritance and other OOP stuffs.
- -Fluorine can help Javascript programmers isolate impure parts in their applications, -so that errors resulted from side-effects can be reduced as much as possible:
- -fluorine.infect()
-
-// Impure function: directly manipulate DOMs in the document.
-// All impure computing should be wrapped with contexts.
-//
-// :: String -> UI ()
-drawMyName = function(name)
-{
- return UI('#name-user').$().text(name).done()
-}
-
-// Pure function: return a plain old string.
-//
-// :: String
-giveName = function()
-{
- return "foobar"
-}
-
-
-Programmers can still mix them in some proper ways, like in a generator function -returing yet another larger context:
- -// :: UI ()
-drawApp = function()
-{
- return UI().
- let(giveName).as('name').
- tie( function()
+It currently has these features:
+
+* [Isolate impure parts in the program.](#isolatation)
+* [Allow to mix pure/impure when necessary.](#unsafe)
+* [Flow-Control](#flow-control), to avoid callback hell.
+* [Laziness](#laziness) (well, sort of) .
+
+It's first inspired by the [Arrowlets](http://www.cs.umd.edu/projects/PL/arrowlets/api-arrowlets.xhtml) library,
+which brought the functional structure, Arrowlet, into Javascript world. Of course, the great [jQuery](http://jquery.com/)
+and [Underscore.js](http://underscorejs.org/) also shown how amazingly Javascript could be.
+
+Futhurmore, this library also want to experiment the possibility of constructing reasonable Javascript programs
+**without (too much) class, object and other OOP things**. Because Javascript, at least according to Douglas Crockford,
+["has more in common with functional languages like Lisp or Scheme than with C or Java".](http://www.crockford.com/javascript/javascript.html)
+This is a good point in this OOP-overflowed age, especailly most of libraries are all eager to provide class, inheritance and other OOP stuffs.
+
+
+## Features
+
+### Isolate Impure Parts in Javascript Applications
+
+Fluorine can help Javascript programmers isolate impure parts in their applications,
+so that errors resulted from side-effects can be reduced as much as possible:
+
+ // Infect whole context to omit prefix namespaces.
+ // You can restore this by call `fluorine.heal()`.
+ fluorine.infect()
+
+ // Impure function: directly manipulate DOMs in the document.
+ // All impure computing should be wrapped with contexts.
+ //
+ // :: String -> UI ()
+ drawMyName = function(name)
+ {
+ return UI('#name-user').$().text(name).done()
+ }
+
+ // Pure function: return a plain old string.
+ //
+ // :: String
+ giveName = function()
+ {
+ return "foobar"
+ }
+
+Programmers can still mix them in some proper ways, like in a generator function
+returing yet another larger context:
+
+
+ // :: UI ()
+ drawApp = function()
+ {
+ return UI().
+ let(giveName).as('name').
+ tie( function()
+ {
+ // Use them just like "let" in other languages.
+ var slc_ex1 = '#ex1'
+ return UI("").$().appendTo('#ex1').done()
+ }).
+ tie( function()
+ {
+ // Fetch the value pre-defined by `let` and `as`.
+ return drawMyName(this.name)
+ }).
+ done()
+ }
+
+
+### Break the Glass in Emergency
+
+Basically, pure functions and values can't arbitrarily mix with impure things:
+
+ // :: String
+ pureString = function()
+ {
+ return "pure"
+ }
+
+ // :: UI String
+ impureString = function()
+ {
+ return UI("impure").done()
+ }
+
+ illegal_string = pureString() + impureString() // Error.
+
+But in some special cases, we can still do that if the context come with some extractor functions:
+
+ illegal_string = pureString() + impureString()().extract() // UI String -> String
+
+Also, we can do some dirty things in the theoretically pure combinator, like the `let` or `_`:
+
+ UI('#name-user').$().
+ _(function(e)
{
- // Use them just like "let" in other languages.
- var slc_ex1 = '#ex1'
- return UI("<div id='name-user'></div>").$().appendTo('#ex1').done()
- }).
- tie( function()
- {
- // Fetch the value pre-defined by `let` and `as`.
- return drawMyName(this.name)
+ // Should keep pure, not violent that like this:
+
+ $(e).text("name changed !")
}).
done()
-}
-
-Basically, pure functions and values now can't arbitrarily mix with impure things:
+Nevertheless, these tricks should be exceptions, not normalities. -// :: String
-pureString = function()
-{
- return "pure"
-}
-// :: UI String
-impureString = function()
-{
- return UI("impure").done()
-}
+### Flow-control
-illegal_string = pureString() + impureString() // Error.
-
+Fluorine use a hidden and stack based process to manage each step in context chains. The most classical example is the `IO` context:
-But in some special cases, we can still do that if the context come with some extractor functions:
- -illegal_string = pureString() + impureString()().extract() // UI String -> String
-
+ IO().
+ get('/ajax/hello').as('hello').
+ get('/ajax/world').as('world').
+ _(function(){ return this.hello + ' ' + this.world }).
+ tie(function(msg)
+ {
+ return UI('').$().text(msg).appendTo('body').done()
+ })
+ done()
-Also, we can do some dirty things in the theoretically pure combinator, like the let
or _
:
UI('#name-user').$().
- _(function(e)
+ function requests()
+ {
+ var responses = {}
+ $.get('/one', function(one)
+ {
+ responses["one"] = one
+ $.get('/two', function(two){
+ responses["two"] = two
+ $.get('/three', function(three){
+ responses["three"] = three
+ $('#io-msg').text(responses["one"]+responses["two"]+responses["three"])
+ })
+ })
+ })
+ }
+
+Into this:
+
+ function requests()
{
- // Should keep pure, not violent that like this:
+ return IO().
+ get('/one').as('one').
+ get('/two').as('two').
+ get('/three').as('three').
+ tie(function()
+ {
+ return UI('#io-msg').$().text(this["one"]+this["two"]+this["three"]).done()
+ }).
+ done()
+ }
- $(e).text("name changed !")
- }).
- done()
-
+Of course there're many flow-control libraries promising this, but Fluorine hope this feature can naturally become a part of context-based computing,
+not a standalone feature.
-This is sometime useful because we may want to embedded 3rd libraries in our contexts.
+Concurrent IOs like initialize multiple requests in the same time is not implemented yet. It will be a important feature in the near future. -Nevertheless, these tricks should be exceptions, not normalities.
+ +### Laziness ( well, sort of ) + +Context chains in Fluorine will not execute immediately, unless it's required. + + // Normal jQuery chain will execute immediately: + act = $('#io-msg').hide().css('background-color', 'cyan').text('New message').fadeIn() + + // Fluorine chain: nothing happened. + act = UI('#io-msg').$().hide().css('background-color', 'cyan').text("New message").fadeIn().done() + +So we can storage the chain to embedded and apply it in anywhere we want + + // Can return entire chain because it will not execute in this function. + function newMessage() + { + return UI('#io-msg').$().hide().css('background-color', 'cyan').text("New message").fadeIn().done() + } + + // When the program initialize, execute it: + newMessage()() + +And because we provide `id` function, using it to directly put a chain in another chain can avoid the annoying anonymous function syntax: + + Event('initialize'). + tie(id( UI('#io-msg').$().hide().css('background-color', 'cyan').text("New message").fadeIn().done() )). + done() + +This is exactly why users should never expect to extract values from IOs: we can't guarrantee the IO chain will +execute and return the value as users wish. In fact, if someone do this: + + var hello = IO(). + get('/ajax/hello'). + done()().extract() + + UI('#io-msg').$().text(hello).done()() + +The `hello` shall be null because the `get` still waiting the response. If values from IO is needed, embedded another contexts in the chain is the standard way to do that: + + IO(). + get('/ajax/hello'). + tie( function( msg ) + { + return UI('#io-msg').$().text(msg).done() + }). + done()() + + +## Dependencies + +* [jQuery](http://jquery.com) : UI context. +* [Underscore.js](http://underscorejs.org) : use it for your good ! + +## Recommends + +* [bacon.js](https://github.com/raimohanska/bacon.js) : FRP programming + + + + + + + + + diff --git a/index.md b/index.md deleted file mode 100644 index 79bd7c7..0000000 --- a/index.md +++ /dev/null @@ -1,110 +0,0 @@ - -# Fluorine: a context based Javascript library - -Fluorine is a Javascript library and eDSL, want to help developers constructing their -application with more functional features, and build large programs from small functions. -It currently has these features: - -* Allow to isolate impure parts in the program. -* Still allow mixing pure/impure parts when necessary. -* Flow-control, to avoid callback hell. -* (Sort of) laziness. -* (Partially) typed. - -It's first inspired by the [Arrowlets](http://www.cs.umd.edu/projects/PL/arrowlets/api-arrowlets.xhtml) library, -which brought functional structure, the Arrowlet, into Javascript world. Of course, the great [jQuery](http://jquery.com/) -and [Underscore.js](http://underscorejs.org/) also shown how amazingly Javascript could be. - -Futhurmore, this library also want to experiment the possibility of constructing reasonable Javascript programs -**without (too much) class, object and other OOP things**. Because Javascript, at least according to Douglas Crockford, -["has more in common with functional languages like Lisp or Scheme than with C or Java".](http://www.crockford.com/javascript/javascript.html) -This is a good point in this age of OOP-mainstreaming, especailly most of libraries are all eager to provide class, inheritance and other OOP stuffs. - - -## Features - -### Isolate Impure Parts in Javascript Applications - -Fluorine can help Javascript programmers isolate impure parts in their applications, -so that errors resulted from side-effects can be reduced as much as possible: - - fluorine.infect() - - // Impure function: directly manipulate DOMs in the document. - // All impure computing should be wrapped with contexts. - // - // :: String -> UI () - drawMyName = function(name) - { - return UI('#name-user').$().text(name).done() - } - - // Pure function: return a plain old string. - // - // :: String - giveName = function() - { - return "foobar" - } - -Programmers can still mix them in some proper ways, like in a generator function -returing yet another larger context: - - - // :: UI () - drawApp = function() - { - return UI(). - let(giveName).as('name'). - tie( function() - { - // Use them just like "let" in other languages. - var slc_ex1 = '#ex1' - return UI("").$().appendTo('#ex1').done() - }). - tie( function() - { - // Fetch the value pre-defined by `let` and `as`. - return drawMyName(this.name) - }). - done() - } - - -### Break the Glass in Emergency - -Basically, pure functions and values now can't arbitrarily mix with impure things: - - // :: String - pureString = function() - { - return "pure" - } - - // :: UI String - impureString = function() - { - return UI("impure").done() - } - - illegal_string = pureString() + impureString() // Error. - -But in some special cases, we can still do that if the context come with some extractor functions: - - illegal_string = pureString() + impureString()().extract() // UI String -> String - -Also, we can do some dirty things in the theoretically pure combinator, like the `let` or `_`: - - UI('#name-user').$(). - _(function(e) - { - // Should keep pure, not violent that like this: - - $(e).text("name changed !") - }). - done() - -This is sometime useful because we may want to embedded 3rd libraries in our contexts. - -Nevertheless, these tricks should be exceptions, not normalities. -