I'd argue (and in fact we have in the academic literature) that JuMP.jl is a DSL for mathematical programming, e.g.
m = Model() @defVar(m, x[1:5], Bin) @addConstraint(m, sum{x[i], i=1:5; iseven(i)} <= 2) solve(m) Notice the sum{ } On Sunday, November 16, 2014 10:45:57 AM UTC-5, Isaiah wrote: > > No! The expression between *begin ... end* must still be valid Julia >> syntax, which is why you need to tell Julia, not to parse it into a Julia >> AST, but into some intermediate representation. >> > > Well, in the examples you showed the command block is passed as string > anyway, so the more accurate analogy is: > > julia> @Scala """ > blah > """ > > But there is already a nicer way to do this: > > julia> macro Scala_mstr(args) > ... > end > > then you can do this directly and the contents of the string will be > passed to the macro (as a raw string): > > julia> Scala""" > ... > """ > > (e.g. this is used in Keno's Cxx.jl for embedding C++ code as strings) > > This seems like a good solution, except that some people might not like > using string blocks in such a way. Personally I think it's fine: there must > be a reserved block start/end pair one way or another. > > > On Sun, Nov 16, 2014 at 10:26 AM, Simon Danisch <sdan...@gmail.com > <javascript:>> wrote: > >> No! The expression between *begin ... end* must still be valid Julia >> syntax, which is why you need to tell Julia, not to parse it into a Julia >> AST, but into some intermediate representation. >> @Scala begin >> person match { >> ERROR: syntax: extra token "match" after end of expression >> >> >> 2014-11-16 16:18 GMT+01:00 Johan Sigfrids <johan.s...@gmail.com >> <javascript:>>: >> >>> Would it be impossible to simply have something like: >>> >>> @Scala begin >>> >>> person *match* { >>> *case* Person("Hans","Meyer",7) => "Found: Hans Meyer" >>> * case* Person("Heinz","Mustermann",28) => "Found: Heinz Mustermann" >>> * case* *_* => "Unknown Person" >>> } >>> end >>> >>> >>> Without having to have the multiline string thing or DSL call? >>> >>> On Saturday, November 15, 2014 11:55:15 PM UTC+2, Simon Danisch wrote: >>>> >>>> Hi, >>>> I was thinking about Domain Specific Languages lately from different >>>> perspectives and concluded, that we could "easily" make Julia an awesome >>>> home for DSL's. (Domain Specific Languages) >>>> Why would Julia benefit from a good infrastructure for DSL's? >>>> >>>> *1.)* >>>> Rapid prototyping of language concepts. >>>> I was considering Mauro's trait implementation lately, and I didn't >>>> want to use it, because it just looked a little cumbersome (no offense, >>>> its >>>> just a little difficult with only macros!). >>>> If he was able to implement the prototype first with a DSL, he could >>>> have already created a syntax prototype for it and thinks could have >>>> looked >>>> more concise and inviting. >>>> >>>> *2.)* >>>> Writing in different languages inside Julia, for example Assebler, >>>> OpenCL kernels, OpenGL shader, etc... >>>> function foo(a::Float32, b::Float32) >>>> @DSL Assembler(a, b)""" >>>> push RBP >>>> mov RBP, RSP >>>> vaddss XMM0, XMM0, XMM1 >>>> pop RBP >>>> ret >>>> """ >>>> end >>>> I know you might ask, why this is a good idea, as LLVM should be tuned, >>>> to emit the best native code. >>>> But lets assume that it doesn't! Then, a person can already prototype >>>> how the code emitted by LLVM should look like, and another person, who >>>> probably knows LLVM a lot better, can do the appropriate changes to >>>> LLVM/Julia. >>>> >>>> *3.)* >>>> Classic use cases like a specialized UI languages, first order logic, >>>> other mathematical constructs, scripting, etc... >>>> >>>> *4.)* >>>> Stealing nice syntactic concepts from other language, to see if they >>>> give Julia any advantages, without a big hassle. >>>> function isspecificperson(person) >>>> @DSL Scala""" >>>> >>>> person *match* { >>>> *case* Person("Hans","Meyer",7) => "Found: Hans Meyer" >>>> *case* Person("Heinz","Mustermann",28) => "Found: Heinz Mustermann" >>>> *case* *_* => "Unknown Person" >>>> } >>>> >>>> """ >>>> >>>> *Possible disadvantages: * >>>> If widely used, code will get harder to read, as you need to learn all >>>> the crazy DSL's users are creating. >>>> But this will happen anyways, and it's probably better to do it in an >>>> orderly fashion than ;) >>>> >>>> *Implementation Sketch:* >>>> >>>> macro DSL(name, text) >>>> tokens = *dsltokenizer*(DSLTokens{name}(), text)::DSLTokens{name} >>>> dslast = *generate_ast*(tokens)::AST{name} >>>> return *dsl*(dslast)::AST{:Julia} >>>> end >>>> >>>> # Default implementations: >>>> *dsltokenizer*(::DSLTokens, text) = ... # Default probably with Jake >>>> Bolewkis Lexer?! >>>> *generate_ast*(text::DSLTokens) = ... >>>> *dsl*(ast::AST) = ... >>>> #Depending on the complexity of your DSL, overwrite any of these >>>> stages, to implement your own DSL, otherwise use default >>>> >>>> >>>> It seems like Jake Bolewski has already implemented a lot to make this >>>> work. >>>> Probably it would be nice to integrate OpenCL kernel code like this ;) >>>> My hope would also be, to pair this with meta data on the different >>>> stages, to make it very easy to supply correct syntax >>>> highlighting/correction for the different DSL's. >>>> Creating the ast and tokenizing things otherwise needs to be done >>>> twice, one time for the system and one time for an IDE. >>>> Or are there currently simple ways in Julia, to determine where tokens >>>> are in a string, what scopes there are and what kind of attribute println >>>> is in "println("1234")" ? >>>> I haven't found them yet. Most of the things you would currently need >>>> to implement for this, will be redundant to "parse" and are then volatile >>>> to changes in the language. >>>> >>>> Well these are just some thoughts I recently had, feel free to evaluate >>>> this and/or judge if this is something we really want! >>>> I won't implement this anytime soon, but maybe someone searching for a >>>> bachelor/master thesis comes to the rescue? >>>> Who knows... >>>> >>>> Cheers, >>>> Simon >>>> >>> >> >