Naive suggestion: since you can eval inside the macro body (à la 
FastAnonymous), couldn't your generated function expand into a macro call?

On Friday, August 12, 2016 at 12:19:49 PM UTC-4, Erik Schnetter wrote:
>
> On Fri, Aug 12, 2016 at 4:06 AM, Tomas Lycken <tomas....@gmail.com 
> <javascript:>> wrote:
>
>> Julia’s parametric types are not generic enough to support this.
>>
>> In my experience, any time I’ve been inclined to reason like this about 
>> one of my use cases, someone (usually Tim Holy :P) has been able to show me 
>> a way that works just fine, without magic, by just using the type system in 
>> a smarter way than I was able to figure out myself. So, if you’ll forgive 
>> my delusions of grandeur, I’ll attempt to suggest a way to support the 
>> cases you’ve mentioned so far!
>>
>> The code turned out to be quite lengthy, so I put it in a gist instead: 
>> https://gist.github.com/tlycken/e501e1079d947d699b71941d93b7113e
>>
> That's similar to the approach I'm currently trying. The added difficulty 
> is that I don't know ahead of time how many fields I need in the immutable 
> type, hence I'm passing a single type parameter that is a tuple.
>
> Also, I really want the type generating function to be type-stable. If I 
> relax this restriction, then I can keep my current code, use a regular (not 
> generated) function, and call `eval` there to create the type I needed 
> (properly memoized of course). However, this makes code that first declares 
> a variable and then uses it quite inefficient; one will always have to put 
> the variable declaration and its use into separate functions, declaring 
> variables "further outside", so that Julia's method call selection can 
> allow type inference to kick in.
>
> -erik
>  
>
>> Basically, what I’ve done is to create a generic type that holds all the 
>> information you need ((lower bound, stride, end) for each dimension) in 
>> its type arguments, and then a generator function that lets you specify 
>> these the same way you do today - with symbols as placeholders to be filled 
>> in when instantiated.
>>
>> The generator function won’t be type stable, because the return type will 
>> depend on values of keyword arguments, but that shouldn’t be a big problem 
>> since it’s just upon array initialization; I suspect you will do the actual 
>> work in some kernel function, which then has access to the full type 
>> information.
>>
>> // T
>>
>> On Friday, August 12, 2016 at 7:38:07 AM UTC+2, Andy Ferris wrote:
>>
>> > I'm encountering the error "eval cannot be used in a generated 
>>> function" in Julia 0.5 for code that is working in Julia 0.4. 
>>>
>>> I feel your pain, Erik!
>>>
>>> > AFAICT, it remains possible to do dynamic type generation if you (1) 
>>> print the code that would define the type to a file, and (2) `include` the 
>>> file. 
>>>
>>> While this is true, is your example meant to be a generated function? If 
>>> I need to recreate an existing type by calling `create_type_dynamically` 
>>> again with the same parameters, it won't be free at run-time. Unless we can 
>>> get it to recompile, and `isdefined()` is `@pure` or (evaluated by 
>>> inference)... hmm...
>>>
>>> > The definition of a generated function is "a pure function which 
>>> computes a function body based solely upon properties of the input argument 
>>> types". Since `eval` isn't pure, that would violate the definition of what 
>>> `@generated` is, and therefore it isn't usable. This isn't supposed to be 
>>> complicated, what an `@generated` function is actually supposed to be 
>>> allowed to do is just extremely limited, to make sure the system doesn't 
>>> fall apart on edge cases.
>>>
>>> Jameson - I suppose most of us think not of Julia as like the C or C++ 
>>> language standards, but as an implementation. A beautifully hackable 
>>> implementation, at that! I would assert that the definition of a generated 
>>> function is written in C++, lisp, Julia, etc. So it seemed to us users that 
>>> what "pure" meant was in this context was whatever we observed to work: 
>>> that it should always produce the same output code, and it seemed obvious 
>>> that the generator itself runs one or more times before the function is 
>>> called. Side effects that don't cause the compiler to get confused? Well, 
>>> why not? We can `println` in the generator, and that is rather useful for 
>>> debugging. In the past months several people have independently come up 
>>> with the same incredibly useful trick/hack, and there is now a bit of 
>>> sadness felt that our clever/insane code has died!
>>>
>>> I'm not saying this is terribly bad. Fixing #265 would be wonderful, and 
>>> we shouldn't get in the way of that. But Julia has always appeared to be 
>>> driven by community desires, and I feel these generated types are pretty 
>>> nifty. Constructive thoughts on any way forward would be greatly 
>>> appreciated. As would an actual example of this not working as expected in 
>>> the current implementation of Julia (though I think you may have provided 
>>> this for planned work on #265??).
>>>
>> ​
>>
>
>
>
> -- 
> Erik Schnetter <schn...@gmail.com <javascript:>> 
> http://www.perimeterinstitute.ca/personal/eschnetter/
>

Reply via email to