On Sun, Aug 14, 2016 at 6:13 PM, Adrian Salceanu <[email protected]>
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