Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

How to gauge possibility of using? #34

Open
haf opened this issue May 19, 2018 · 6 comments
Open

How to gauge possibility of using? #34

haf opened this issue May 19, 2018 · 6 comments

Comments

@haf
Copy link

haf commented May 19, 2018

Let's say I wanted to compile Logary (the core library) with Fez; can it be done? It depends on NodaTime and Hopac and FSharp.Core so it has minimal dependencies IMO.

@kjnilsson
Copy link
Owner

Right now it's probably not possible to compile modules that depend on external libraries. It should be reasonably easy to do however assuming we use a .NET core project file. What would happen then is that the calls into the external libraries would be generated but they would not exist so you would have to re-implement them in erlang. Depending on the complexity of the dependency this may or may not be worth doing.

fez isn't (and can never be) "F# on the BEAM" - what it can be however is a tool for using the F# language to write good erlang. Hence integrating with the existing F# ecosystem isn't a goal that can be met.

Might be worth flicking through this slide deck as well:
https://docs.google.com/presentation/d/1yos-mvWd01_78UNLpTpvABlyhizbp5td_91b03AuO7E/edit?usp=sharing

@haf
Copy link
Author

haf commented May 19, 2018

Right now it's probably not possible to compile modules that depend on external libraries.

I see. I suppose this means the BCL as well then.

However, have you considered the foundations of a BCL? Like a socket abstraction? And writing a parser (which would require access to a span-type/array-scoped abstraction)?

On the language side-of-things: reflection API? Quotations? Typed quotations/holes?

The F* compiler goes through a series of steps, finally arriving at C that compiles cross-platform. Can similar things done with types here? Closures? Generics?

See my comment

I don't think you address the Hopac question. Why implement Async then?

@kjnilsson
Copy link
Owner

Yes the BCL is effectively out of scope although it will generate mod calls which you can fill in with erlang implementations.

You can interact with the existing erlang apis using the [<ModCall>] attribute which includes sockets, files etc.

"reflection API? Quotations? Typed quotations/holes?"

yes all out unless someone comes up with some way to utilise them.

Compiling to c and compiling to core erlang are two very different things. When on the BEAM you have to play by the rules of the BEAM. Attempting anything else is typically bound to fail.

Closures are supported as they are supported in erlang. Generics are just a compile type thing. Nothing survives into core erlang.

About Hopac is the question whether fez should support a hopac-like api? or implement Hopac in erlang. I don't really see the point given erlang has it's own concurrency model but am happy to be shown otherwise.

@haf
Copy link
Author

haf commented May 19, 2018

My point about F* is that you can layer compilers as long as you're ok with static compilation only and leave much of the runtime types wayside (which this repo does). You're basically saying that F# becomes a subset of itself with this constraint; but perhaps it would be good to consider a compile-time reflective model, like quotation was meant to give you, which lets you manipulate the AST as values during runtime. See e.g. The (Little|Reasoned) Schemer and how they use the AST as a tool for constructing abstractions and machine learning. If you'd constrain it, it would be fine too; DUs, vars, functions, lists/seqs would get you a long way — you could even add a constraint of local-variables only and start with non-recursion and without while-constructs; effectively giving you a total functional programming language that you can prove eventually terminates (by having all variants always decrease).

The model above is good enough for a lot of things; e.g. music software usually written in C++, can have its filters running concurrently if their memory models promise side-effect free execution (the const-lambdas in C++11); the AST could then be evaluated and replaced at runtime, like Erlang supports, and you could have all your code as mealy machines (which is what Qvitoo uses internally for all side-effects), fully replaceable at runtime. Mealy machines in turn can be used/generalised to FSM machines running in lockstep in distributed fashion, possibly giving you Byzantine fault tolerance or alternatively giving you distributed stream processing like MillWheel/Flink.

I don't think Erlang's concurrency model is very effective since it's both async and without guarantees of message delivery. You have to scaffold a lot on top of that to make your programs safe. What I think you need to reach a broad audience are two things;

  • concurrency in the small; in process, with synchronous commit/nack semantics as a superset of CSP; this implies a share-nothing memory model between processes and a mutable, strict memory model within a process, like the Hopac docs make the case for
  • parallelism in the small; SIMD/data parallelism (https://pdfs.semanticscholar.org/5501/42f3939c530ad48237cd28ce965ccbf00818.pdf http://manticore.cs.uchicago.edu/)
  • concurrency in the large; out of process, with atomic broadcast and strong eventual consistency built into the libraries in use:
    • Partisan — for discovery and membership
    • Atomic broadcast like https://github.com/lasp-lang/plumtree so you don't have to implement RCP retries every time you send a message
    • An entity model; like LASP gives you, but with support for regular strictly serialisable operations on entities as well as strongly eventually consistent.
  • concurrency small<->large interop should model the "in the large" invariants in the type system with the compiler being able to optimise away much of the pattern matching and DU union evaluation (like Fable + JS Closure compiler does: DU switch statements can compile down to an int comparison). Or in other words: avoiding the CORBA/WS-* mistakes, while avoiding the Erlang async-unknown mistakes.
  • parallelism in the large: Tensorflow/stream processing/DAGs compiling to executable ASTs/agents.

I think it comes down to what you want to do with Fez. I'm interested because almost all my libraries are implemented completely as code and without much reflection, purely in F#; but they do assume the CSP-alike concurrency model that CML/F#/.Net lets you have, which in turn is based on the memory models that we programmers have grown accustomed to.

Personally, I'm interested in F# as a language because I like (C)ML, strict evaluation and a strong compiler that can go to great lengths to optimise my code. But I think this is wrong:

Hence integrating with the existing F# ecosystem isn't a goal that can be met

It can indeed be met, by introducing enough constraints in a considered and clear manner. I took Logary as an example, because there's only reflection in the serialisation logic; but we might as well use picklers if that would enable cross-compilation. The rest is pure F# and a concurrency model. The same for Suave, really; zero reflection.

@haf
Copy link
Author

haf commented Dec 15, 2018

How is this project progressing?

@kjnilsson
Copy link
Owner

With a 3rd child arrived, 9 months of house renovations and a challenging full-time job this project has not progressed. :) Who knows what the new year will bring though. I did a little bit of hacking on an attempt to better support erlang behaviours (and thus OTP) through interfaces but I haven't completed it yet.

There is still the question of F# suitability as a language to target the BEAM with. Happily sitting on the fence with that for now.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants