Comments (4)
So I thought about this a little bit more.
First of all, the type of reify
can actually be simplified to forall a. a -> AST
.
So when an expression is reified, simply replace reify a
with the serialised AST of a
. If there are any free variables in a, recursively generate ASTs for those. If a free variable references a Declaration
from another module, first resolve that and then continue as above (is this possible with the current module system?)
Furthermore, taint all binders referenced by free variables in a
as "reified" and replace their type with something equivalent to (AST, x)
for any binder x
. When a dependent module calls a function with a tainted argument, reify it and pass the AST along the original value.
I.e:
M1:
value :: Int
value = 1
M2:
f :: (Int -> Int) -> AST
f g = reify (g M1.value)
M3:
test :: Int
test = M2.f (\x -> x * 2)
Now, there are two free variables in the expression passed to reify
in M2.f
: g
and M1.value
. M1.value
is a declaration in M1
, so just generate its AST normally. g
references a binder, so taint it (using some simplified AST notation here):
f :: (AST, Int -> Int) -> AST
1: f (gAST, g) = gAST `Abs` reify M1.value
2: f (gAST, g) = gAST `Abs` Lit 1
Now, M3.test
calls M2.f
. Its first argument is tainted however, so pass along its AST:
test :: Int
1: test = f (reify (\x -> x * 2), \x -> x * 2)
Now continue the process as above, recursively. Since there are no free variables in \x -> x * 2
, just generate its AST:
2: test = f (Var x `Abs` (Var x `App` Op "*" `App` Lit 2), \x -> x * 2)
I don't think the type checker needs to be modified for that, because the tainted flag just tells every call site to replace exp
with (reify exp, exp)
. That should be enough.
from purescript.
As a first step, what about a built-in primitive like:
reify :: a -> (AST -> b) -> b
An example:
f = reify (if 1 == 1 then True else False) print
Basically, reify
inlines the AST of the first argument into the second argument. Some issues/questions:
- The reified AST needs to be complete, i.e. free variables need to be recursively inlined. As an alternative, something like
a -> (Tuple AST (Map Var AST) -> b) -> b
may be good enough, whereMap Var AST
is the environment of all bindings in scope. - Can this be implemented as a simple desugaring step? Should be doable, except when the AST references something from another module. Are all imported modules available when desugaring a module?
The most obvious use case for something like this is sending code over the wire, Erlang-style. Right now this is only possible with some sort of restricted custom DSLs (+ free monads etc), where things like if
or case
need to be encoded as combinators, losing things like exhaustivity checking in the process.
from purescript.
Why this is closed?
from purescript.
As per the linked issue #2749, it needs an amount of research and a proper fleshed out proposal.
from purescript.
Related Issues (20)
- Extend CoreFn's Int literal encoding with a stringified value HOT 8
- LTS 21.7 for ghc-9.4.5
- Bad rejection of some instances of classes with fundeps. (Or misleading error message) HOT 1
- CI's Ubuntu build doesn't hit the cache
- Core dump for Linux Arm64 release with ArchlinuxARM HOT 5
- Improve accessibility for the generated docs HOT 7
- Parser accepts @ binders in class heads
- Have more information in DuplicateSelectiveImport
- Support `--source-globs FILE` argument due to Windows' `cmd.exe` character limitation
- Problem typing a let expression HOT 1
- Replace `npm-installer` usage with `purs-installer` HOT 1
- Pattern matching between identical let-bindings produce no shadowing errors HOT 4
- Type synonym impossible to fully apply in type application HOT 2
- Missing all metadata for custom error
- Using an infix type alias in a type application crashes the compiler.
- Document syntax for qualified operators HOT 1
- Record field access using raw strings breaks parser HOT 1
- Code doesn't typecheck when moving a type alias between modules
- Can't unify two equal type literals in some cases
- `a = b` does not typecheck despite `a` and `b` having the same type and `b` typechecks HOT 1
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 purescript.