Thanks

Maybe I wasn't clear enough - otherwise, can you please elaborate, I'm 
definitely still poking around, any clarifications would be highly 
appreciated. 

> creating a new module
-> the module is available at compile time (the users of the templating 
system will place the vars in there, by convention). 

> parse julia code
-> it's not really parsing julia code, it has no meaning at the point. It's 
simply basic string processing and it's fast - tried with a 10K lines HTML 
file, no sweat. 

> defining globals 
-> why are they globals? include_string() is used inside a function, inside 
a module within the app. 

> eval in a module
-> true, but then what can we do? That's the way of doing metaprogramming 
in Julia, and it's widely used, isn't it? 
I guess that would be the price for not having to do 
print("<html><head>...") like our ancestors used to in PHP or ASP, when not 
being chased by tigers (or something around that age). 


duminică, 14 august 2016, 15:01:47 UTC+2, Yichao Yu a scris:
>
>
>
> On Sun, Aug 14, 2016 at 6:13 PM, Adrian Salceanu <[email protected] 
> <javascript:>> wrote:
>
>> Variables contained in a module and then parsed Julia code included 
>> within a function using include_string(). 
>>
>> Any obvious performance issues with this approach? 
>>
>
> Everything about it?
> Literally every steps are hitting the slow path that is only meant to 
> execute at compile time and not runtime. Including
>
> Creating a new module, parse julia code, eval in a module, defining 
> globals.
>  
>
>>
>>
>> duminică, 14 august 2016, 12:11:06 UTC+2, Adrian Salceanu a scris:
>>>
>>> OK, actually, that's not nearly half as bad. Variables contained in a 
>>> module 
>>>
>>> include("src/Ejl_str.jl")
>>> using Ejl
>>>
>>>
>>> module _
>>>   couñtry = "España"
>>>   lang = "en"
>>> end
>>>
>>>
>>> function render_template()
>>>   tpl_data = ejl"""
>>> <% if _.lang == "en" :>
>>> Hello from me, ...
>>> <: else :>
>>> Hola
>>> <: end %>
>>>
>>>
>>> %= _.couñtry == "España" ? "Olé" : "Aye"
>>> moo
>>> """
>>>
>>>
>>>   include_string(join(tpl_data, "\n"))
>>>   join(____output, "\n")
>>> end
>>>
>>>
>>> render_template() |> println
>>>
>>> Hello from me, ...
>>>
>>>
>>> Olé
>>> moo
>>>
>>>
>>> duminică, 14 august 2016, 11:20:37 UTC+2, Adrian Salceanu a scris:
>>>>
>>>> Thanks
>>>>
>>>> Yes, I've thought about a few ways to mitigate some of these issues: 
>>>>
>>>> 1. in the app I can setup a module (like Render) and evaluate into this 
>>>> module exclusively. 
>>>> Hence, another approach might be to have some helper methods that setup 
>>>> the variables in the module and then eval the template itself inside the 
>>>> module too (must try though). So something in the lines of: 
>>>> set(:foo, "foo")
>>>> set(:bar, [1, 2, 3])
>>>> parse_tpl(ejl"""$(foo) and $(bar)""")
>>>> # all the above gets parsed in Render
>>>>
>>>> 2. break the parsing in 2 steps: 
>>>> a. reading the template string and parse it to generated Julia code (as 
>>>> strings) (an array of Julia code lines) - cache it 
>>>> b. (load strings from cache and) eval the code together with the vars 
>>>>
>>>> ===
>>>>
>>>> Another approach (which is how it's done in one of the Ruby templating 
>>>> engine) is to generate a full function definition, whose body parses the 
>>>> template and takes the variables as params. And then eval and execute the 
>>>> function with its params. However, I'm still struggling with the 
>>>> metaprogramming API as for instance parse() chokes on multiple lines, and 
>>>> I 
>>>> couldn't find a functional equivalent of a quote ... end blocks. But I'm 
>>>> hoping include_string() will do the trick (must test though). 
>>>>
>>>>
>>>> sâmbătă, 13 august 2016, 15:20:01 UTC+2, Yichao Yu a scris:
>>>>>
>>>>>
>>>>>
>>>>> On Sat, Aug 13, 2016 at 8:06 PM, Adrian Salceanu <[email protected]
>>>>> > wrote:
>>>>>
>>>>>> That's pretty difficult as my goal is to use embedded Julia as the 
>>>>>> templating language. Similar to Ruby's ERB, ex: 
>>>>>> http://www.stuartellis.eu/articles/erb/
>>>>>>
>>>>>> So say in the template I have something like 
>>>>>>
>>>>>> <% if foo == "bar" %>
>>>>>> Bar
>>>>>> <% else %>
>>>>>> Baz
>>>>>> <% end %>
>>>>>>
>>>>>> The idea is to use Julia itself to parse the code block and Julia 
>>>>>> will raise an error is foo is not defined. So I can't really look it up. 
>>>>>>
>>>>>
>>>>> It's ok to use the julia syntax and parser but it's a pretty bad idea 
>>>>> to use the julia runtime to actually evaluating the expression, and 
>>>>> absolutely not by making them reference to local variables.
>>>>>
>>>>> For a start you are not allowed to reference local variables by names 
>>>>> anyway.
>>>>> You also shouldn't allow reference to/overwrite of other local 
>>>>> variables (i.e. the template namespace should be fully isolated and 
>>>>> independent of any scope in the template engine).
>>>>>
>>>>> Since you want to eval, it seems that efficiency is not an issue, in 
>>>>> which case you can create an anonymous module and eval/create globals in 
>>>>> that module. This should also be reasonably fast if you are only using 
>>>>> the 
>>>>> template once.
>>>>>
>>>>> If you want to use it multiple time and compile the template, you 
>>>>> should then scan for variable references in the expressions and process 
>>>>> it 
>>>>> from there.
>>>>>  
>>>>>
>>>>>>
>>>>>> I can either do 
>>>>>>
>>>>>> <% if _[:foo] == "bar" %> 
>>>>>>
>>>>>> or 
>>>>>>
>>>>>> <% if _(:foo) == "bar" %>
>>>>>>
>>>>>> but it's not that nice. 
>>>>>>
>>>>>>
>>>>>> sâmbătă, 13 august 2016, 13:24:18 UTC+2, Yichao Yu a scris:
>>>>>>>
>>>>>>>
>>>>>>>
>>>>>>> On Sat, Aug 13, 2016 at 7:13 PM, Adrian Salceanu <
>>>>>>> [email protected]> wrote:
>>>>>>>
>>>>>>>> Thanks
>>>>>>>>
>>>>>>>> It's for a templating engine. The user creates the document (a 
>>>>>>>> string) which contains interpolated variables placeholders and markup. 
>>>>>>>> When 
>>>>>>>> the template is rendered, the placeholders must be replaced with the 
>>>>>>>> corresponding values from the dict.
>>>>>>>>
>>>>>>>> The lines in the template are eval-ed and so Julia will look for 
>>>>>>>> the variables in the scope. So the vars should be already defined.
>>>>>>>>
>>>>>>>
>>>>>>> You should explicitly look up those variables in the dict instead.
>>>>>>>  
>>>>>>>
>>>>>>>>
>>>>>>>> Yes, ultimately I can force the user to use a dict (or rather a 
>>>>>>>> function for a bit of semantic sugar) - which is preferable from a 
>>>>>>>> performance perspective, but less pretty end error prone from the user 
>>>>>>>> perspective.
>>>>>>>
>>>>>>>
>>>>>>>
>>>>>
>

Reply via email to