On Fri, 2016-07-22 at 10:18, Marius Millea <[email protected]> wrote:
> Yea, thats a good point. Granted for my purpose I'm never going to be
> redefining these types mid program. I suppose one might extend your @unpack
> to work on an expression and do the substitution recursively like my thing
> does, then you could write,
>
> @unpack aa: a function(x,aa:A)
> sin(2pi/a*x)
> a = 3 #can also assign without repacking
> end
For functions and loops, it seems much better to have the `@unpack`
inside, no? For begin-end blocks, you could just use a let instead:
let
@unpack aa: a
sin(2pi/a*x)
end
(Or are you worried about performance? The extra bindings introduced
are optimized away (I think).)
> which seems slightly less hacky than what I'm doing but serves a similar
> purpose.
>
> Marius
>
>
> On Fri, Jul 22, 2016 at 9:01 AM, Mauro <[email protected]> wrote:
>
>>
>> On Fri, 2016-07-22 at 01:02, Marius Millea <[email protected]> wrote:
>> >> FYI Mauro's package has something similar
>> >> <http://parametersjl.readthedocs.io/en/latest/manual/>.
>> >>
>> >
>> > Some interesting stuff in there, thanks!
>>
>> The problem with your `@self` and with Parameters.jl's
>> `@unpack_SomeType` macros is that it is easy to introduce bugs.
>> Consider:
>>
>> type A # and register it with @self
>> a
>> end
>> @self f(x,aa:A) = sin(2pi/a*x)
>>
>> Sometime later you refactor type A:
>>
>> type A
>> a
>> pi
>> end
>>
>> now your function f is broken. So, for every change in type A you need
>> to check all functions which use `@self`.
>>
>> Instead I now use the @unpack macro (and its companion @pack), also part
>> of Paramters.jl. Then above f becomes
>>
>> function f(x,aa::A)
>> @unpack aa: a
>> sin(2pi/a*x)
>> end
>>
>> This is still much more compact than writing out all the aa.a, etc. (if
>> there are lots of field accesses) but safe. Also, it clearly states, at
>> the top of the function, which fields of a type are actually used.
>>