Settings

Theme

Embedding the F# Compiler

queil.net

50 points by kkdaemas 4 years ago · 12 comments

Reader

dharmaturtle 4 years ago

I have ~8 months of Clojure experience and ~3 years of F#. Clojure's REPL and feedback loop is bloody marvelous. F# also has a REPL, but it doesn't compare. However I still prefer F#'s type-safety. (I believe) a key part of how Clojure's REPL works is by compiling top level forms into JVM instructions which it puts into global mutable scope. Clojure can run on the CLR, so it seems this should be possible with F# as well. It would be cool if F# could temporarily bypass type-safety to quickly iterate on a module before plugging it back into the rest of an assembly and re-enabling type safety. There's no reason to recompile everything when all I want is to test out a 1 line delta independent of its... uh... dependents.

Basically, I want Jupyter-stype notebooks to be my primary dev environment. The blog goes in that direction, but calling code via

    let result = assembly |> extract<string -> Async<unit>> "This.Is.A.Namespace.HelloHost.myFunc"
is just yuck. What I want probably requires language level changes.
  • gavinray 4 years ago

    I hear this amazement and fascination with REPL's that people have and I don't understand.

    In a REPL, you're given a buffer to enter text into, and it evaluates it as you submit this buffer.

    This is fine if you live in an age before graphical editors, but today we have tools with a better REPL-like experience.

    In VS Code, I can use extensions to show realtime values next to every line of my program, and indicators of whether a branch/code path was ever hit.

    This allows me to use an entire file as a visual REPL with instant feedback.

    Using an actual REPL sucks compared to being able to regularly edit a file in your editor and get all of this + more without being handicapped to a terminal buffer.

    Notebooks are also a worse experience for the same reason. You need to manually trigger "cells", which return a single value/visualization, or add a bunch of print statements.

    JavaScript:

    https://quokkajs.com/

    Python:

    https://marketplace.visualstudio.com/items?itemName=xirider....

    Scala:

    https://scalameta.org/metals/docs/editors/vscode/#worksheets

    You can find something like this for most languages, either in VS Code or Jetbrains IDE's

    • vrgfa 4 years ago

      Agreed. I dislike all REPLs except maybe the Lisp one. In SML, OCaml, F# they are less useful anyway since the strength of these languages is to build up huge (but sound) abstractions.

      I think the fascination with REPLs, especially in the Python world, is that it allows one to produce flashy web page snippets or Jupiter notebooks that look like work while they are really trivial (there is a similarity here to pg's remark that Java is partly popular because the boilerplate looks like work).

    • dunefox 4 years ago

      These things are just the editor plugin executing the code in a background REPL and showing the output inside the editor, no? While for example real-time updates are pretty cool, I don't see how that makes it not REPL driven development. Nothing is stopping you from having this in Common Lisp (and I'm kind of sure CL already has this in emacs).

      Also, this doesn't really allow for everything else Lisp has that go well with the REPL: conditions and restarts, interactive inspection of values and stack frames, etc.

    • platz 4 years ago

      does it fire the missles? how does it handle IO? what if we are poking global mutable state?

  • phillipcarter 4 years ago

    > Basically, I want Jupyter-stype notebooks to be my primary dev environment.

    You're in luck!

    https://marketplace.visualstudio.com/items?itemName=ms-dotne...

    Works best with Plotly support as well: https://plotly.net

  • caseymarquis 4 years ago

    Haven't read the article yet. That can probably be padded over with some reflection. I don't really use F# (it's on the list of things to learn when my current job cools down a bit, doing 80 hours a week right now), but I use reflection in C# all the time.

    It's not too hard to iterate through all classes/functions/constructs in an assembly and create a cache. Additionally, the generic type parameters can be avoided by adding a parameter that looks like what you want to pull out. I'm on mobile, but you could make a library that does something like (excuse the C# syntax):

        Lib.Cache(assembly);
        var myFunc = Lib.Pull(myFunc => async (int a, string b) => "");
    
    That could throw an exception if there's a naming conflict and it's not able to find the function with only the name and signature. A second parameter could take part of a namespace/class name in that case. This is pseudo code, but I'm pretty sure I could get something similar up and running.

    Side note: If anyone is using F# and hiring, shoot me an email!

    • queil 4 years ago

      > the generic type parameters can be avoided by adding a parameter that looks like what you want to pull

      It's possible but what's wrong with the generic type parameter? It's an unequivocal way of specifying of what type is expected on the other side.

  • queil 4 years ago

    @dharmaturtle

    My aim here was different. I wanted to enable extending compiled F# apps with F# scripts. Think of scripts being plugins implementing a specific public interface the hosting app defines.

vrgfa 4 years ago

F# is underrated and MSFT should promote it more (instead of promoting the "open" source Python efforts).

queil 4 years ago

I have never expected my blog post to be in Hacker News. The aim of all of it is to be able to have F#-script-powered plugins in otherwise compiled code. Check out my example here: https://github.com/queil/fsc-host/blob/main/examples/Compile...

Keyboard Shortcuts

j
Next item
k
Previous item
o / Enter
Open selected item
?
Show this help
Esc
Close modal / clear selection