Skip to content

Instantly share code, notes, and snippets.

@fahadsuhaib
Created January 25, 2012 09:50
Show Gist options
  • Save fahadsuhaib/1675681 to your computer and use it in GitHub Desktop.
Save fahadsuhaib/1675681 to your computer and use it in GitHub Desktop.
Pit jQuery integration
/// Pit jQuery API - Experimental version, modifies Pit AST to generate proper jQuery output
document.GetElementById("check")
|> jQuery.ofEl
|> jQuery.attr3 ([|"src","/images/hat.gif";"title","jQuery";"alt","jQuery logo"|])
|> jQuery.css3 ("background","red")
|> jQuery.ignore
/// Uses pipelining in F# to generate jQuery related code.
return Pit.FSharp.Core.Operators.op_PipeRight(Pit.FSharp.Core.Operators.op_PipeRight(Pit.FSharp.Core.Operators.op_PipeRight(Pit.FSharp.Core.Operators.op_PipeRight(document.getElementById("check"))(function(x) {
return $(x);
}))(function(t) {
return t.attr({
src: "/images/hat.gif",
title: "jQuery",
alt: "jQuery logo"
});
}))(function(t) {
return t.css("background", "red");
}))(function(t) {
return t;
});
@fahadsuhaib
Copy link
Author

This is an experimental version of Pit generating JS that works with jQuery. It will be modified later so the compiler stuff is generic. I dint wanted to go the way of using “types returning types aka pipelining C# way” that would have allowed easier JS generation, It just dint make sense when using with F#. Like, I can’t properly define a series of functions in different lines, using Types were limiting to the same line and lots of fuss over it.

I'll try to see if there is a generic way to identify the pipelining pattern internally in the compiler or somehow expose that to the compiler extension and change the AST to generate exactly like jQuery, As of now I'll go with the above pattern and later deal with optimizing it.

@t0yv0
Copy link

t0yv0 commented Jan 25, 2012

|> is nasty stuff. a |> b evaluates as let x = a in let y = b in y x. It is tempting to convert a |> b to b a but b a evaluates as let y = b in let x = a in y x. You notice that there is a change in the side effect order, therefore the reduction can only be made if you can prove that it does not matter, for example when a and b have no side effects.

I would not bother. I see no problem with writing F# in "fluent" style:

A
    .B(...)
    .C(...)

You definitely would want to do name interning though, Pit.FSharp.Core.Operators.op_PipeRight is too long.

@fahadsuhaib
Copy link
Author

Thanks for that info there. The way to use this mode is to always specify the pipeline operator and not do the b(a) kind of evaluation, so the compiler extension can identify the pattern and change the order, it works only that way now. The reason about not leaning towards "fluent" style is about readability and F# way of doing things. I do agree that it is much easier with fluent style to define the types and be done with it, but using it is simply a pain when you have lots of code nested inside each other, and moreover If I'm writing lots of F# code in my project I dont want to see odd code right in the middle of it with fluent style.

Like I said, the option of identifying the pipeline pattern and generating JS that is equal to jQuery is pretty much doable (I'm not looking at it now), and users would find using |> the same way as they are used to work with Seq / List / Array.

I'm gona do extensive testing before I see this thru, but thanks for your comments, like the details of |> evaluating. About the interning, Yep, thats in the todo, Have to find a tricky way to get it properly aliased, but then its not in the immediate works.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment