
Hi All, I was thinking about doing an EDSL for Makefile (as an exercise) I put down my line of thought here - http://hpaste.org/40233/haskell_makefile_edsl I'd appreciate some feedback on the approach. Also, I wanted some idea on how(in the current approach) I could make the target name and the dependency available to the action writer - as shown below. r1 = Rule { target = "file1", dependsOn = ["file2"], action = do execute ("gcc -c " ++ dependencyList ++ " -o " ++ target) } -- Regards, Kashyap

Hi,
You might want to take a look at http://github.com/nfjinjing/nemesis
which is somewhat related.
Warren
On Thu, Sep 30, 2010 at 1:41 AM, C K Kashyap
Hi All, I was thinking about doing an EDSL for Makefile (as an exercise) I put down my line of thought here - http://hpaste.org/40233/haskell_makefile_edsl
I'd appreciate some feedback on the approach. Also, I wanted some idea on how(in the current approach) I could make the target name and the dependency available to the action writer - as shown below.
r1 = Rule { target = "file1", dependsOn = ["file2"], action = do execute ("gcc -c " ++ dependencyList ++ " -o " ++ target) }
-- Regards, Kashyap

Hi Warren,
You might want to take a look at http://github.com/nfjinjing/nemesis which is somewhat related.
The above looks like a DSL approach and not an EDSL approach. -- Regards, Kashyap

On 30/09/10 09:41, C K Kashyap wrote:
Hi All, I was thinking about doing an EDSL for Makefile (as an exercise) I put down my line of thought here - http://hpaste.org/40233/haskell_makefile_edsl
I'd appreciate some feedback on the approach. Also, I wanted some idea on how(in the current approach) I could make the target name and the dependency available to the action writer - as shown below.
r1 = Rule { target = "file1", dependsOn = ["file2"], action = do execute ("gcc -c " ++ dependencyList ++ " -o " ++ target) }
Neil Mitchell gave a talk at AngloHaskell 2009 on doing a better make in Haskell. I've found the abstract on the wiki: http://www.haskell.org/haskellwiki/AngloHaskell/2009 but, alas, no slides to be found. My memory was that he had implemented the system successfully for internal use at a company and it had worked out quite well. Perhaps you can contact him about the slides. Thanks, Neil.

Thanks Neil and Warren.
On Thu, Sep 30, 2010 at 3:32 PM, Neil Brown
On 30/09/10 09:41, C K Kashyap wrote:
Hi All, I was thinking about doing an EDSL for Makefile (as an exercise) I put down my line of thought here - http://hpaste.org/40233/haskell_makefile_edsl
I'd appreciate some feedback on the approach. Also, I wanted some idea on how(in the current approach) I could make the target name and the dependency available to the action writer - as shown below.
r1 = Rule { target = "file1", dependsOn = ["file2"], action = do execute ("gcc -c " ++ dependencyList ++ " -o " ++ target) }
Neil Mitchell gave a talk at AngloHaskell 2009 on doing a better make in Haskell. I've found the abstract on the wiki: http://www.haskell.org/haskellwiki/AngloHaskell/2009 but, alas, no slides to be found. My memory was that he had implemented the system successfully for internal use at a company and it had worked out quite well. Perhaps you can contact him about the slides.
Thanks,
Neil.
-- Regards, Kashyap

Hi,
What great timing! I will be giving a talk at the Haskell Implementors
Workshop tomorrow about the Make system Shake. It will be video taped
and I can send you the slides after I've given the talk. So wait a
day, and I'll give you all the answers.
Thanks, Neil
On Thu, Sep 30, 2010 at 6:02 AM, Neil Brown
On 30/09/10 09:41, C K Kashyap wrote:
Hi All, I was thinking about doing an EDSL for Makefile (as an exercise) I put down my line of thought here - http://hpaste.org/40233/haskell_makefile_edsl
I'd appreciate some feedback on the approach. Also, I wanted some idea on how(in the current approach) I could make the target name and the dependency available to the action writer - as shown below.
r1 = Rule { target = "file1", dependsOn = ["file2"], action = do execute ("gcc -c " ++ dependencyList ++ " -o " ++ target) }
Neil Mitchell gave a talk at AngloHaskell 2009 on doing a better make in Haskell. I've found the abstract on the wiki: http://www.haskell.org/haskellwiki/AngloHaskell/2009 but, alas, no slides to be found. My memory was that he had implemented the system successfully for internal use at a company and it had worked out quite well. Perhaps you can contact him about the slides.
Thanks,
Neil. _______________________________________________ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe

On Thu, Sep 30, 2010 at 13:05, Neil Mitchell
Hi,
What great timing! I will be giving a talk at the Haskell Implementors Workshop tomorrow about the Make system Shake. It will be video taped and I can send you the slides after I've given the talk. So wait a day, and I'll give you all the answers.
Will you publish the tool too? ;-) /M -- Magnus Therning (OpenPGP: 0xAB4DFBA4) magnus@therning.org Jabber: magnus@therning.org http://therning.org/magnus identi.ca|twitter: magthe

What great timing! I will be giving a talk at the Haskell Implementors Workshop tomorrow about the Make system Shake. It will be video taped and I can send you the slides after I've given the talk. So wait a day, and I'll give you all the answers.
Will you publish the tool too? ;-)
No :-( [or at least not yet] Wait for the talk, and I'll explain more. Thanks, Neil

Hi Neil ... how did the talk go?
On Thu, Sep 30, 2010 at 10:23 PM, Neil Mitchell
What great timing! I will be giving a talk at the Haskell Implementors Workshop tomorrow about the Make system Shake. It will be video taped and I can send you the slides after I've given the talk. So wait a day, and I'll give you all the answers.
Will you publish the tool too? ;-)
No :-( [or at least not yet]
Wait for the talk, and I'll explain more.
Thanks, Neil _______________________________________________ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
-- Regards, Kashyap

Neil's * slides http://www.galois.com/~dons/talks/hiw-2010/ndm-shake.pdf * video http://www.vimeo.com/15465133 ckkashyap:
Hi Neil ... how did the talk go?
On Thu, Sep 30, 2010 at 10:23 PM, Neil Mitchell
wrote: What great timing! I will be giving a talk at the Haskell Implementors Workshop tomorrow about the Make system Shake. It will be video taped and I can send you the slides after I've given the talk. So wait a day, and I'll give you all the answers.
Will you publish the tool too? ;-)
No :-( [or at least not yet]
Wait for the talk, and I'll explain more.
Thanks, Neil _______________________________________________ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
-- Regards, Kashyap _______________________________________________ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe

Thanks Neil
On Sat, Oct 2, 2010 at 10:07 AM, Don Stewart
Neil's
* slides http://www.galois.com/~dons/talks/hiw-2010/ndm-shake.pdf * video http://www.vimeo.com/15465133
ckkashyap:
Hi Neil ... how did the talk go?
On Thu, Sep 30, 2010 at 10:23 PM, Neil Mitchell
wrote: What great timing! I will be giving a talk at the Haskell Implementors Workshop tomorrow about the Make system Shake. It will be video taped and I can send you the slides after I've given the talk. So wait a day, and I'll give you all the answers.
Will you publish the tool too? ;-)
No :-( [or at least not yet]
Wait for the talk, and I'll explain more.
Thanks, Neil _______________________________________________ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
-- Regards, Kashyap _______________________________________________ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
-- Regards, Kashyap

How about: execute ("gcc -c " ++ dependencyList ++ " -o " ++ target r1) / Emil 2010-09-30 10:41, C K Kashyap skrev:
Also, I wanted some idea on how(in the current approach) I could make the target name and the dependency available to the action writer - as shown below.
r1 = Rule { target = "file1", dependsOn = ["file2"], action = do execute ("gcc -c " ++ dependencyList ++ " -o " ++ target) }

On Thu, Sep 30, 2010 at 5:35 PM, Emil Axelsson
How about:
execute ("gcc -c " ++ dependencyList ++ " -o " ++ target r1)
/ Emil
Thanks Emil ... yeah, that works...I was wondering what I could do to not have to mention "r1" explicitly. I'll check out Neil's pdf and video now - perhaps I'll find answers there. -- Regards, Kashyap

Thanks Emil ... yeah, that works...I was wondering what I could do to not have to mention "r1" explicitly. I'll check out Neil's pdf and video now - perhaps I'll find answers there.
I checked out the video - nice - but I think, understandably, since its not open source yet, not much of implementations details were mentioned. So, I have this "unanswered question" nagging in my head. In the example below, how can I let the makefile writer refer to the target name and dependencies. Likr Emil mentioned, I could use "target r1" but I want to avoid having to mention r1. http://hpaste.org/40233/haskell_makefile_edsl -- Regards, Kashyap

If you don't want to mention "r1" explicitly, but want to refer to
"target", "sources" and such only a monadic approach (e.g. Reader
Monad) might be what you want.
On Oct 3, 6:14 am, C K Kashyap
Thanks Emil ... yeah, that works...I was wondering what I could do to not have to mention "r1" explicitly. I'll check out Neil's pdf and video now - perhaps I'll find answers there.
I checked out the video - nice - but I think, understandably, since its not open source yet, not much of implementations details were mentioned.
So, I have this "unanswered question" nagging in my head. In the example below, how can I let the makefile writer refer to the target name and dependencies. Likr Emil mentioned, I could use "target r1" but I want to avoid having to mention r1.
http://hpaste.org/40233/haskell_makefile_edsl
-- Regards, Kashyap _______________________________________________ Haskell-Cafe mailing list Haskell-C...@haskell.orghttp://www.haskell.org/mailman/listinfo/haskell-cafe

On Sun, Oct 3, 2010 at 5:22 PM, steffen
If you don't want to mention "r1" explicitly, but want to refer to "target", "sources" and such only a monadic approach (e.g. Reader Monad) might be what you want.
Thanks Steffen ... would you be able to give me an example? -- Regards, Kashyap

The Reader monad just establishes an environment, so you can use "ask"
to retrieve a value from the environment.
Let's say you have the following types representing you Make-
Environment:
data MakeInfo = MakeInfo
{ target_ :: String
, sources_ :: [String]
}
then inside your Monad you can access MakeInfo using "ask". Because
you may want to have IO available, let's use the Monad Transformer
version of the Reader Monad, to define our MakeMonad:
type MakeMonad = ReaderT MakeInfo IO
runMake :: MakeMonad () -> MakeInfo -> IO ()
runMake m makeInfo = runReaderT m makeInfo
and runMake will run it.
Then you can access source and target e.g. with Applicatives:
test = do
sources <- sources_ <$> ask
target <- target_ <$> ask
system $ "gcc -o " ++ target ++ " " ++ (foldl (++) $ map ('
':) sources)
Since using "sources_ <$> ask" and such may still be annoying, this
gist[1] uses some (questionable) TypeClass-hackery and some extension
to overcome this "problem"...
Using this solution one can simply write:
test = sh $ "gcc -o" & target & sources
which looks somewhat nicer. This example also defines runTest and a
test function (which calls the shell command "echo" to print some
lines) you can try in ghci by typing "runTest test"...
[1] http://gist.github.com/614246
On 3 Okt., 16:56, C K Kashyap
On Sun, Oct 3, 2010 at 5:22 PM, steffen
wrote: If you don't want to mention "r1" explicitly, but want to refer to "target", "sources" and such only a monadic approach (e.g. Reader Monad) might be what you want.
Thanks Steffen ... would you be able to give me an example?
-- Regards, Kashyap _______________________________________________ Haskell-Cafe mailing list Haskell-C...@haskell.orghttp://www.haskell.org/mailman/listinfo/haskell-cafe

which looks somewhat nicer. This example also defines runTest and a test function (which calls the shell command "echo" to print some lines) you can try in ghci by typing "runTest test"...
Thank you very much Steffen for taking the time out for the example ... I'll study the code. -- Regards, Kashyap

I checked out the video - nice - but I think, understandably, since its not open source yet, not much of implementations details were mentioned.
Yes, it's unfortunate.
So, I have this "unanswered question" nagging in my head. In the example below, how can I let the makefile writer refer to the target name and dependencies. Likr Emil mentioned, I could use "target r1" but I want to avoid having to mention r1.
If it helps, written in Shake, this would be: main = do want ["file1"] "file1" *> \x -> do need ["file2"] putStrLn "Hello" putStrLn "World" Thanks, Neil

Hello C, Sunday, October 3, 2010, 6:59:25 PM, you wrote:
Thanks Neil,
main = do want ["file1"] "file1" *> \x -> do need ["file2"] putStrLn "Hello" putStrLn "World"
What if I want to mention "file1" only once?
mention_only_once file action = do want [file] file *> action main = mention_only_once "file1" $ \x -> do need ["file2"] putStrLn "Hello" putStrLn "World" -- Best regards, Bulat mailto:Bulat.Ziganshin@gmail.com

mention_only_once file action = do want [file] file *> action
main = mention_only_once "file1" $ \x -> do need ["file2"] putStrLn "Hello" putStrLn "World"
Thanks Bulat .... I guess even this should work - main = do let file1="file1" want [file1] file1 *> \x -> do need ["file2"] putStrLn "Hello" putStrLn "World" -- Regards, Kashyap

Telling from the video and the slide, Neil's make system is actually
really cool. Indeed something I would really enjoy to use. It support
dynamic and static dependency tracking (more or less) out of the box
(by storing dependencies in a database file).
So you use "want" and "need" to tell the system about the static and
dynamic dependencies.
The "want" at the beginning just tells which targets to start.
Since you may want to choose your task via command line, you actually
would want to do something like:
main = do
wantDefault "file1" =<< getArgs
"file1" *> ...
wantDefault default [] = want [default]
wantDefault _ args = want args
Since using String everywhere for dependencies can lead to errors, it
is always a good idea to replace the strings by constants you can
reuse.
Shake is more kind of a library. If you want a more make-like System
you can even write a preprocessor (like the haskell sinatra clone
"bird"), which even looks for your target symbols and then generates a
haskell file with target symbols replaced by Strings.
I hope the space leaks will be fixed in the future, so one can even
write long running processes which automatically detect changes and
rerun without user interaction and much more.
I actually wonder about the semantic differences between want and
need. Is need used to tell about dynamic dependencies and want for
static dependencies?
On 4 Okt., 05:41, C K Kashyap
mention_only_once file action = do want [file] file *> action
main = mention_only_once "file1" $ \x -> do need ["file2"] putStrLn "Hello" putStrLn "World"
Thanks Bulat .... I guess even this should work -
main = do let file1="file1" want [file1] file1 *> \x -> do need ["file2"] putStrLn "Hello" putStrLn "World"
-- Regards, Kashyap _______________________________________________ Haskell-Cafe mailing list Haskell-C...@haskell.orghttp://www.haskell.org/mailman/listinfo/haskell-cafe

Hi
Telling from the video and the slide, Neil's make system is actually really cool. Indeed something I would really enjoy to use.
Thanks :-)
So you use "want" and "need" to tell the system about the static and dynamic dependencies. The "want" at the beginning just tells which targets to start. Since you may want to choose your task via command line, you actually would want to do something like:
main = do wantDefault "file1" =<< getArgs "file1" *> ...
Yep, that's certainly one way of doing it (and a very natural way of doing it).
Since using String everywhere for dependencies can lead to errors, it is always a good idea to replace the strings by constants you can reuse.
You can also use wildcards everywhere (i.e. have a rule for *.exe), and then you only give each file once - but anyone duplicating any complex thing like a string more than once should either use a let or write a combinator on top of it - either works just fine.
Shake is more kind of a library. If you want a more make-like System you can even write a preprocessor (like the haskell sinatra clone "bird"), which even looks for your target symbols and then generates a haskell file with target symbols replaced by Strings.
It doesn't even need to generate a Haskell file, you can sequence these operations dynamically in a Monad and use Shake as a backend target for anything. Haskell is great :-)
I hope the space leaks will be fixed in the future, so one can even write long running processes which automatically detect changes and rerun without user interaction and much more.
Yes, although in practice you could probably already do it without issue. I think the space leak is incredibly shallow, and could be fixed in a few hours.
I actually wonder about the semantic differences between want and need. Is need used to tell about dynamic dependencies and want for static dependencies?
You could always do: "PHONY" *> \_ -> do need xs Instead of want xs, and have the system know about PHONY specially. want is a way of kicking off the initial set, and need is doing it after that - the real difference is the monad they run in and nothing else. The semantic idea is that "want" expresses that you the end user wants to have these files available, while the rules "need" to have files available before they continue - it's entirely possible they should be overloaded over the two monads. Thanks, Neil
On 4 Okt., 05:41, C K Kashyap
wrote: mention_only_once file action = do want [file] file *> action
main = mention_only_once "file1" $ \x -> do need ["file2"] putStrLn "Hello" putStrLn "World"
Thanks Bulat .... I guess even this should work -
main = do let file1="file1" want [file1] file1 *> \x -> do need ["file2"] putStrLn "Hello" putStrLn "World"
-- Regards, Kashyap _______________________________________________ Haskell-Cafe mailing list Haskell-C...@haskell.orghttp://www.haskell.org/mailman/listinfo/haskell-cafe
Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
participants (9)
-
Bulat Ziganshin
-
C K Kashyap
-
Don Stewart
-
Emil Axelsson
-
Magnus Therning
-
Neil Brown
-
Neil Mitchell
-
steffen
-
Warren Henning