Closed crockeea closed 10 years ago
I guess that you are using syntactic
1.x, which is not the same as the master branch.
In 1.x, to evaluate with binding your domain has to be a higher-order domain as in: https://github.com/emilaxelsson/syntactic/blob/1.x/examples/NanoFeldspar/Core.hs#L130
However, it is often easier to work with the sugared syntax.
In the NanoFeldspar example, there is a function share
which will bind an expression:
g :: (Syntax b) => (Data Index -> b) -> b
g f = share (value 5) $ \v -> f v
How soon can we expect v2.0 on Hackage?
Here is how to do what you want in syntactic-2.0:
import Data.Proxy
import Data.Syntactic
import Data.Syntactic.TypeUniverse
import Data.Syntactic.Constructs
import Data.Syntactic.Evaluation
data Let a where Let :: Let (a :-> (a -> b) :-> Full b)
instance Render Let where renderSym Let = "Let"
instance Eval Let t where toSemSym Let = Sem (flip ($))
instance StringTree Let
type Types = IntType :+: FunType
tr :: Typeable Types a => TypeRep Types a
tr = typeRep
type Dom = BindingT Types :+: Construct :+: Let
lit :: Show a => a -> ASTF Dom a
lit a = inj (Construct (show a) a)
f :: ASTF Dom a -> ASTF Dom a
f = id
g :: ASTF Dom Int
g = inj Let :$ lit (5 :: Int) :$ (inj (LamT tr 0) :$ f (inj $ VarT tr 0))
test1 = drawAST g
test2 = evalClosed (Proxy :: Proxy Types) g
Notes:
Let
is no longer included in the library, so it has to be defined. (I should probably include it, though.)Types
, tr
) is needed in order to do evaluation. If evaluation is not needed, one can use Binding
instead of BindingT
and then type representations are not needed, so things get simpler and type signatures can be omitted, etc.As Anders says, it's usually better (in the user front end) to use higher-order syntax. I've now added share
to NanoFeldspar in the master branch so that Anders' example works.
How soon can we expect v2.0 on Hackage?
It has been releasable since a few days ago. I'm holding it off in order not to cause confusion, since 1.x is still alive and used by Feldspar (until it gets rewritten).
Another thing is that I've removed quite some stuff from Syntactic (predefined symbols such as Let
, the code motion transform, etc.) that maybe someone will be missing (though I don't know if there are any actual users :) ). I would like to be able to point to alternatives for these things. One alternative is comp-edsl, which I'm currently working on. But it's not quite ready to be released yet. As another alternative, I'm considering making a separate package syntactic-utils
containing stuff that has been removed.
Let me know if you need syntactic-2.0 released urgently.
I've got a satisfactory solution for this with syntactic-2.0
, so I'll post it here in case it helps someone else: https://gist.github.com/crockeea/920071d88fb4f02c6caa
I'm trying to figure out how to use Let/Lambda to share a result, but I get the feeling I'm rather off track.
My impression is that I should do something like the following:
The idea is to make a
Let
that binds some expression(literal 5)
as the argument to aLambda
. The lambda binds its argument tovar0
, which is then referenced in some expression. This seems logical, and I can even make it compile, but I cannot evaluate this expression. I've tried usingevaluate
, butLambda
does not have an instance forEval
. I've also triedevalBind
, but there is no instance(Top :< Typeable)
(my domain is a compound domain,dom ~ Variable :+: Let :+: Lambda :+: ...
).Aside from the evaluation problems, I'm wary of my solution since HigherOrder.hs warns against explicitly using
Variable
. I'm not sure if I should be concerned with that or not. Unfortunately, I've been unable to find an example of result sharing in the Feldspar example.What is the recommended way to create evaluatable code sharing?