Comments (6)
I think the mutability drawback of ETS pretty much invalidates its use unfortunately. @lepoetemaudit I like your suggestion in IRC of using synthesized (presumably nullary?) functions to house these values and I very much want to avoid anything other than literal values for these to start with. I think when we allow things like function application, matches, and receives to be assigned to "values" we have a couple of problems:
- memoizing the result on first access if it's computed at runtime, this way lies lazy evaluation as in Haskell and I have a pretty strong dislike of "lazy by default".
- compile time expressions, all kinds of side effect concerns about when something is computed.
Longer term I think CTEs would be interesting to explore but I believe we should be cautious about how we approach those. With respect to allowable expressions, I suspect we'll need to add a check to either the AST or code generation stage that throws a compilation error if a value contains any of the following:
- receive
- match
- function application
- spawn (and in future link, monitor, etc as those will need to be involved in typing as well and aren't strictly function application in Alpaca)
Is it worth considering replacing references to a top-level value/constant with their literals in the code generation step? I confess I haven't really thought this through entirely yet :)
Thoughts?
from alpaca.
Would it be helpful if we were able to mark functions as pure / impure during compilation, using the criteria you listed? I'm not against allowing function application in values, as long as any applied functions are also pure - this way, ultimately even at compile time we could resolve a value to a literal. I'm undecided on whether at that point we substitute references with their literals or insert a call to a nullary function - I think I'd rather insert a function call as values could potentially be very large so repeating them for each use would bloat the generated module.
Actually, on that last point, the advantage of calculating at runtime is that if a large literal is calculated, it doesn't bloat the module code - perhaps CTEs should be a future thing and then we could let the programmer decide what is optimal for their situation (or introduce dreaded macros to achieve the same).
I agree on avoiding lazy by default, but if calculating at runtime I'm not against the calculation step happening at the module level on module load. As we discussed these values could live in nullary functions in a runtime-generated module.
from alpaca.
I'm a bit reluctant to get into inferring purity right now especially since we're likely to rely so heavily on the FFI unless anything that uses that is automatically considered impure. Correspondingly if something's marked pure
by a user we have to have a way of guaranteeing that. Mostly I think it's a bit complex to solve quickly/immediately though I'm definitely interested in exploring effect typing further down the road, possibly even as a gradual typing extension. Hence my focus on literals :)
I'm all for CTEs being a future thing, I think that's another area that's going to take some careful thought along with things like effect typing.
Bottom line: I'm basically fine with calculating these things at runtime but I'd still like to restrict them to literals. Maybe I'm getting hung up on the notion of these being "constants" and what that means.
Missing anything? Aspects of purity simpler than I think?
from alpaca.
It's a tough nut to crack. I'd be very happy with just literals as a first step - after all, there's always the fallback of using a single arg function that takes unit (it's just that it can lead to some extra parens in some cases, e.g. funcB (funcA ())
as opposed to merely funcB valueA
, and will feel a little odd at first to people coming from other MLs.
I'm not sure if purity would be so hard to determine (but I haven't explored it in any depth, so I'm far from certain on that). Essentially if a function doesn't contain any FFI (apart from maybe some functions that we whitelist), receive, spawn etc., apply an impure function, or do anything that could throw an error, it could be used as part of a value expression.
Having thought more about storing these values etc., I think we should just compute them at compile time (as long as it's safe to do so - literals will certainly be safe!) and put them in a nullary function right in the same module. The important thing is referential transparency - memoization of any kind is really just an optimisation that can be considered later.
from alpaca.
Seems like a pretty solid place to start! Comfortable tackling this? I'm more than happy to help with questions. #62 and then #68 are on my list in the near term along with trying to work out an Erlang Factory talk ;)
from alpaca.
Sure, I'll have a go :)
from alpaca.
Related Issues (20)
- Function parsing as incorrect arity with ADT as first arg HOT 2
- Auto-imported pipe operator HOT 2
- Treat types with a single unqualified member as aliases HOT 1
- Overlap between function heads and match expression HOT 1
- How to type Erlang terms without built-in types. HOT 7
- alias module name HOT 1
- Zero arity functions HOT 5
- Inconsistent function case HOT 2
- Compile error with type signature annotation
- Defining the function (>>) does not yield a helpful error
- Use values to signify test pass/fail rather than exceptions
- Can't find a way to contact the creator/mantainers of alpaca :) HOT 2
- ReasonML HOT 4
- provide prebuilt "binaries" for OTP 21
- Status? HOT 4
- "Overloaded" records with constructors in patterns fail instead of getting a proper warning.
- Incorrect line numbers for missing record field errors
- clarify - nominal or structural type system HOT 3
- ADT argument in function header crashes compiler
- Non-exhaustive patterns in "match" expressions HOT 2
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from alpaca.