I can understand that if you're used to building interfaces that use R's
non-standard evaluation and reified environments heavily, it can be
frustrating to not have those features. But I don't think that means that
you cannot build convenient and safe interfaces for data analysis.

On Fri, Jul 24, 2015 at 11:48 AM, Brandon Taylor <
brandon.taylor...@gmail.com> wrote:

> Ok, maybe I was being harsh when I used the word mis-marketing. The post
> here: http://julialang.org/blog/2012/02/why-we-created-julia/
> specifically mentions that one of Julia's goals is to be as easy for
> statistics as R. Building a domain specific language is more difficult (but
> clearly not impossible) without environment access. Again, the examples I'm
> most familiar with are in the Hadleyverse (see previous posts in this
> thread for links to vignettes). Also, this is probably the fifth time that
> me being stubborn seems to have caused tensions on threads, and I'm sorry
> for that. Learning a bit about C compilers convinced me that I was
> completely wrong about environments needing to be implemented for scoping
> to work.
>
>
> On Friday, July 24, 2015 at 3:46:28 AM UTC-4, Milan Bouchet-Valat wrote:
>
>> Le jeudi 23 juillet 2015 à 15:31 -0700, Brandon Taylor a écrit :
>> > I'm not saying inherent slowness will be particularly useful. I'm
>> > saying environment access will be particularly useful. The point of
>> > Julia is no compromise between speed and code-ability. If it is not
>> > possible to integrate environment access and speed, then I think that
>> > Julia is mis-marketing itself, at least as a viable R alternative.
>> Could you give us a concrete example of what you would like to do with
>> environments? I haven't encountered cases where I would personally miss
>> this R feature in Julia, so I don't understand what you're trying to
>> achieve.
>>
>> Also, note that when we say that a solution will be slow in Julia, it
>> doesn't mean that it would be slower than in R. It's just that to write
>> code approximately equivalent to C, you cannot use the same solutions
>> as R.
>>
>>
>> Regards
>>
>>
>> > On Friday, July 24, 2015 at 12:35:13 AM UTC+4, Yichao Yu wrote:
>> > > On Thu, Jul 23, 2015 at 4:23 PM, Brandon Taylor
>> > > <brandon....@gmail.com> wrote:
>> > > > Will it cause a slowdown because there is a better way to do it
>> > > or will it
>> > > > cause a slowdown because something inherent about environment
>> > > access?
>> > > > Because if the second is the case, then it would be worth it, at
>> > > least to
>> > > > me.
>> > >
>> > > AFAICT, environment access is basically global variable and it will
>> > > trash any optimization julia can do so in some sense the slow down
>> > > is
>> > > inherent about environment access.
>> > >
>> > > I don't see why the inherent slowness would be particularly useful
>> > > though.
>> > >
>> > > >
>> > > > On Thursday, July 23, 2015 at 11:13:14 AM UTC+8, Yichao Yu wrote:
>> > > >>
>> > > >> On Wed, Jul 22, 2015 at 10:51 PM, Brandon Taylor
>> > > >> <brandon....@gmail.com> wrote:
>> > > >> > Ok, made some progress. Still having trouble with a _ENV_ not
>> > > defined
>> > > >> > error:
>> > > >> > how could it not be defined if it's a global variable???
>> > > Figuring out
>> > > >> > argument passing is going to be tricky. Is this kind of system
>> > > feasible
>> > > >> > or
>> > > >> > is it going to cause huge slowdowns?
>> > > >>
>> > > >> It'll cause a huge slowdown.
>> > > >>
>> > > >> >
>> > > >> > using DataFrames
>> > > >> >
>> > > >> > import Base.convert
>> > > >> >
>> > > >> > _TYPES_ = Symbol[]
>> > > >> >
>> > > >> > type _LAZY_
>> > > >> >   _E_::Expr
>> > > >> >   _ENV_::Symbol
>> > > >> > end
>> > > >> >
>> > > >> > # modify dicts such that if a key is not found, search the
>> > > parent
>> > > >> > function Base.getindex{K,V}(h::Dict{K,V}, key)
>> > > >> >   index = Base.ht_keyindex(h, key)
>> > > >> >   if index < 0
>> > > >> >     if :_parent in keys(h)
>> > > >> >       Base.getindex(eval(h[:_parent]), key)
>> > > >> >     else
>> > > >> >       throw(KeyError(key))
>> > > >> >     end
>> > > >> >   else
>> > > >> >     h.vals[index]::V
>> > > >> >   end
>> > > >> > end
>> > > >> >
>> > > >> > # allow inheritance from modules
>> > > >> > function convert(::Type{Dict}, m::Module)
>> > > >> >   dict = Dict()
>> > > >> >   for name in names(m)
>> > > >> >     dict[name] = eval( :(Base.$name) )
>> > > >> >     # add types to type list
>> > > >> >     if typeof(dict[name]) <: DataType
>> > > >> >       push!(_TYPES_, name)
>> > > >> >     end
>> > > >> >   end
>> > > >> >   dict
>> > > >> > end
>> > > >> >
>> > > >> > # allow inheritance from DataFrames
>> > > >> > function convert(::Type{Dict}, d::DataFrame)
>> > > >> > dict = Dict()
>> > > >> >   for name in names(d)
>> > > >> >     dict[name] = d[name]
>> > > >> >     # add types to type list
>> > > >> >     if typeof(dict[name]) <: DataType
>> > > >> >       push!(_TYPES_, name)
>> > > >> >     end
>> > > >> >   end
>> > > >> >   dict
>> > > >> > end
>> > > >> >
>> > > >> > # establish the base environment, save it as global, and point
>> > > it to an
>> > > >> > empty dictionary
>> > > >> > macro _ENV_MACRO_()
>> > > >> >   esc(quote
>> > > >> >     _ENV_ = gensym()
>> > > >> >     _GLOBAL_ = _ENV_
>> > > >> >     eval(quote
>> > > >> >            $_ENV_ = Dict()
>> > > >> >          end)
>> > > >> >   end)
>> > > >> > end
>> > > >> >
>> > > >> > # establish a new environment and point it towards a dict
>> > > daughter of
>> > > >> > the
>> > > >> > old environment
>> > > >> > macro _NEW_ENV_MACRO_()
>> > > >> >   esc(quote
>> > > >> >     _NEW_ENV_ = gensym()
>> > > >> >     eval(quote
>> > > >> >            $_NEW_ENV_ = {:_parent => $(Expr(:quote, _ENV_)) }
>> > > >> >          end)
>> > > >> >     _ENV_ = _NEW_ENV_
>> > > >> >       end)
>> > > >> > end
>> > > >> >
>> > > >> > # establish a new environment and point it towards a dict
>> > > daughter of
>> > > >> > the
>> > > >> > old environment with dict contents
>> > > >> > macro _ADD_ENV_MACRO_(dict)
>> > > >> >   esc(quote
>> > > >> >     _DICT_ = $dict
>> > > >> >     _ADD_ENV_ = gensym()
>> > > >> >     eval(quote
>> > > >> >            $_ADD_ENV_ = convert(Dict, $_DICT_)
>> > > >> >            $_ADD_ENV_[:_parent] = $(Expr(:quote, _ENV_))
>> > > >> >          end)
>> > > >> >     _ENV_ = _ADD_ENV_
>> > > >> >   end)
>> > > >> > end
>> > > >> >
>> > > >> > # jump back in time to the previous generation
>> > > >> > macro _REMOVE_ENV_MACRO_()
>> > > >> >   esc(quote
>> > > >> >     _ENV_ = eval(_ENV_)[:_parent]
>> > > >> >       end)
>> > > >> > end
>> > > >> >
>> > > >> >
>> > > >> > # new types will have to be included in a module at the
>> > > beginning of
>> > > >> > code
>> > > >> > # that module will need to be converted to a Dict along with
>> > > base
>> > > >> > # a namespace will need to be created such that module dicts
>> > > inherit
>> > > >> > from
>> > > >> > each other, with base at the top
>> > > >> >
>> > > >> > @_ENV_MACRO_()
>> > > >> > @_ADD_ENV_MACRO_(Base)
>> > > >> > @_NEW_ENV_MACRO_
>> > > >> >
>> > > >> > # test expression
>> > > >> > e =
>> > > >> >   quote
>> > > >> >     a = 1
>> > > >> >     b = 2
>> > > >> >     test = function()
>> > > >> >       b = a
>> > > >> >     end
>> > > >> >   end
>> > > >> >
>> > > >> >
>> > > >> > # reformat code to use dict scoping
>> > > >> > function _ENV_REPLACE_(_Lazy_::_LAZY_)
>> > > >> >
>> > > >> >   e = copy(_Lazy_._E_)
>> > > >> >   _ENV_ = _Lazy_._ENV_
>> > > >> >
>> > > >> >   # expressions wrapped in _esc will be left alone
>> > > >> >   if length(e.args) > 0
>> > > >> >     if (e.head == :call) & (e.args[1] == :_esc)
>> > > >> >       return e.args[2]
>> > > >> >     end
>> > > >> >   end
>> > > >> >
>> > > >> >   # set a new scope for a new function. This will also have to
>> > > be done
>> > > >> > with
>> > > >> > for loops, modules, etc.
>> > > >> >   if (e.head == :function)
>> > > >> >     # insert a new scope definition into the function
>> > > definition
>> > > >> >     e.args[2].args = [
>> > > >> >       e.args[2].args[1],
>> > > >> >       :(@_NEW_ENV_MACRO_),
>> > > >> >       :(_ENV_REPLACE!_(
>> > > >> >           $(Expr(:block,
>> > > >> >                  e.args[2].args[2:end]...)))),
>> > > >> >       :(@_REMOVE_ENV_MACRO_)]
>> > > >> >
>> > > >> >   # ignore line numbers
>> > > >> >     elseif e.head != :line
>> > > >> >     # for each sentence
>> > > >> >     for i in 1:length(e.args)
>> > > >> >       # replace symbols with their dict scoped version
>> > > >> >       if typeof(e.args[i]) == Symbol
>> > > >> >
>> > > >> >         #avoid types
>> > > >> >         if !(e.args[i] in _TYPES_)
>> > > >> >           e.args[i] = :($_ENV_[$(string(e.args[i]))])
>> > > >> >         end
>> > > >> >
>> > > >> >       # recur into new expressions
>> > > >> >       elseif typeof(e.args[i]) == Expr
>> > > >> >         e.args[i] = _ENV_REPLACE!_(e.args[i], _ENV_)
>> > > >> >       end
>> > > >> >     end
>> > > >> >   end
>> > > >> >   e
>> > > >> > end
>> > > >> >
>> > > >> > function _LAZY_(e::Expr)
>> > > >> >   _LAZY_(e, _ENV_)
>> > > >> > end
>> > > >> >
>> > > >> > macro _LAZY_EVAL_(_Lazy_)
>> > > >> >   esc(quote
>> > > >> >         eval(_ENV_REPLACE_($_Lazy_))
>> > > >> >       end)
>> > > >> > end
>> > > >> >
>> > > >> >
>> > > >> > @_LAZY_EVAL_(_LAZY_(e))
>> > > >> >
>> > > >> > eval(_ENV_)["a"]
>> > > >> > eval(_ENV_)["b"]
>> > > >> > eval(_ENV_)["test"]() ## ERROR HERE
>> > > >> >
>> > > >> >
>> > > >> >
>> > > >> >
>> > > >> >
>> > > >> > On Wednesday, July 22, 2015 at 11:30:10 AM UTC+8, Brandon
>> > > Taylor wrote:
>> > > >> >>
>> > > >> >> More to do:
>> > > >> >> Expressions would also have to be escaped from quoting.
>> > > >> >> If we can't scope types within dicts, it might be necessary
>> > > to have
>> > > >> >> special markers for types so they can avoid being scoped.
>> > > >> >> I don't think that macros will be necessary anymore
>> > > >> >>
>> > > >> >>
>> > > >> >> On Wednesday, July 22, 2015 at 11:14:38 AM UTC+8, Brandon
>> > > Taylor wrote:
>> > > >> >>>
>> > > >> >>> Ok so I've got a good start. I bet John Myles White didn't
>> > > think I
>> > > >> >>> could
>> > > >> >>> get this far. Anyway, I'm getting caught up in defining my
>> > > own escape
>> > > >> >>> function. I'm getting lost in multiple layers of meta.
>> > > >> >>>
>> > > >> >>> using DataFrames
>> > > >> >>>
>> > > >> >>> import Base.convert
>> > > >> >>>
>> > > >> >>> # allow inheritance from modules
>> > > >> >>> function convert(::Type{Dict}, m::Module)
>> > > >> >>> dict = Dict()
>> > > >> >>>   for name in names(m)
>> > > >> >>>     dict[name] = eval( :(Base.$name) )
>> > > >> >>>   end
>> > > >> >>>   dict
>> > > >> >>> end
>> > > >> >>>
>> > > >> >>> base_dict = convert(Dict, Base)
>> > > >> >>>
>> > > >> >>> # allow inheritance from DataFrames
>> > > >> >>> function convert(::Type{Dict}, d::DataFrame)
>> > > >> >>> dict = Dict()
>> > > >> >>>   for name in names(d)
>> > > >> >>>     dict[name] = d[name]
>> > > >> >>>   end
>> > > >> >>>   dict
>> > > >> >>> end
>> > > >> >>>
>> > > >> >>> # modify dicts such that if a key is not found, search the
>> > > parent
>> > > >> >>> function Base.getindex{K,V}(h::Dict{K,V}, key)
>> > > >> >>>   index = Base.ht_keyindex(h, key)
>> > > >> >>>   if index < 0
>> > > >> >>>     if :_parent in keys(h)
>> > > >> >>>       Base.getindex(h[:_parent], key)
>> > > >> >>>     else
>> > > >> >>>       throw(KeyError(key))
>> > > >> >>>     end
>> > > >> >>>   else
>> > > >> >>>     h.vals[index]::V
>> > > >> >>>   end
>> > > >> >>> end
>> > > >> >>>
>> > > >> >>> # test expression
>> > > >> >>> e =
>> > > >> >>>   quote
>> > > >> >>>     a = 1
>> > > >> >>>     # anonymous functions required for proper scoping
>> > > >> >>>     test = function()
>> > > >> >>>       b = a
>> > > >> >>>     end
>> > > >> >>>   end
>> > > >> >>>
>> > > >> >>> # set up the global environment
>> > > >> >>> _env = gensym()
>> > > >> >>> eval(:($_env = [:_parent => base_dict] ) )
>> > > >> >>>
>> > > >> >>>
>> > > >> >>> #_new_env = _env
>> > > >> >>> # this is the code that needs to be escaped
>> > > >> >>> #eval(:($_new_env = [:_parent => eval(_env)] ) )
>> > > >> >>>
>> > > >> >>> # reformat code to use dict scoping
>> > > >> >>> function env_replace!(e::Expr,
>> > > >> >>>                       _env::Symbol = _env)
>> > > >> >>>
>> > > >> >>>   # expressions wrapped in _esc will be left alone
>> > > >> >>>   if length(e.args) > 0
>> > > >> >>>     if (e.head == :call) & (e.args[1] == :_esc)
>> > > >> >>>       return e.args[2]
>> > > >> >>>     end
>> > > >> >>>   end
>> > > >> >>>
>> > > >> >>>   # set a new scope for a new function. This will also have
>> > > to be done
>> > > >> >>> with for loops, modules, etc.
>> > > >> >>>   if (e.head == :function)
>> > > >> >>>     # insert a new scope definition into the function
>> > > definition
>> > > >> >>>           _new_env = gensym()
>> > > >> >>>           e.args[2].args = [
>> > > >> >>>             e.args[2].args[1],
>> > > >> >>>             :_esc(), #### need help here ###
>> > > >> >>>             e.args[2].args[2:end] ]
>> > > >> >>>           _env = _new_env
>> > > >> >>>         end
>> > > >> >>>
>> > > >> >>>   # ignore line numbers
>> > > >> >>>   if e.head != :line
>> > > >> >>>
>> > > >> >>>     for i in 1:length(e.args)
>> > > >> >>>       # replace symbols with their dict scoped version
>> > > >> >>>       if typeof(e.args[i]) == Symbol
>> > > >> >>>         e.args[i] = :($_env[$(string(e.args[i]))])
>> > > >> >>>
>> > > >> >>>       # recur into new expressions
>> > > >> >>>       elseif typeof(e.args[i]) == Expr
>> > > >> >>>         e.args[i] = env_replace!(e.args[i], _env)
>> > > >> >>>       end
>> > > >> >>>     end
>> > > >> >>>   end
>> > > >> >>>   e
>> > > >> >>> end
>> > > >> >>>
>> > > >> >>> # here is an eval that allows evaluation within a certain
>> > > dict scope
>> > > >> >>> function lazy_eval(e::Expr,
>> > > >> >>>                    _env::Symbol = _env)
>> > > >> >>>   eval(env_replace!(e), _env)
>> > > >> >>> end
>> > > >> >>>
>> > > >> >>>
>> > > >> >>> ## TO DO
>> > > >> >>> # fix _esc problem
>> > > >> >>> # prevent environment symbols from being scoped (perhaps
>> > > with a
>> > > >> >>> special
>> > > >> >>> marker)
>> > > >> >>> # rescope for, while, try, catch, finally, let, and type
>> > > >> >>> # perhaps use fast anonymous to avoid performance slowdowns?
>> > > >> >>>
>> > > >> >>>
>> > > >> >>> On Tuesday, July 21, 2015 at 10:10:58 AM UTC+8, Brandon
>> > > Taylor wrote:
>> > > >> >>>>
>> > > >> >>>> And there would need to be a special marker for them, such
>> > > that if
>> > > >> >>>> I'm
>> > > >> >>>> in function f, f[:a] won't get preprocessed as f[:f][:a]
>> > > >> >>>>
>> > > >> >>>> On Tuesday, July 21, 2015 at 10:03:08 AM UTC+8, Brandon
>> > > Taylor wrote:
>> > > >> >>>>>
>> > > >> >>>>> Although that would probably require nested dicts. Each
>> > > would have a
>> > > >> >>>>> parent dict, and if a lookup isn't found in the current
>> > > dict, the
>> > > >> >>>>> parent
>> > > >> >>>>> dict would be searched.
>> > > >> >>>>>
>> > > >> >>>>> On Tuesday, July 21, 2015 at 9:53:50 AM UTC+8, Brandon
>> > > Taylor wrote:
>> > > >> >>>>>>
>> > > >> >>>>>> I should be possible to preprocess code such that
>> > > everything is put
>> > > >> >>>>>> into a dict based on the name of enclosing function (and
>> > > global
>> > > >> >>>>>> variables
>> > > >> >>>>>> will just go into a dict called global).
>> > > >> >>>>>>
>> > > >> >>>>>> On Tuesday, July 21, 2015 at 9:42:00 AM UTC+8, Brandon
>> > > Taylor
>> > > >> >>>>>> wrote:
>> > > >> >>>>>>>
>> > > >> >>>>>>> Dicts seem to work pretty well for this kind of thing.
>> > > >> >>>>>>>
>> > > >> >>>>>>> On Tuesday, July 21, 2015 at 9:38:36 AM UTC+8, Brandon
>> > > Taylor
>> > > >> >>>>>>> wrote:
>> > > >> >>>>>>>>
>> > > >> >>>>>>>> I'm getting a cannot assign variables in other modules
>> > > error.
>> > > >> >>>>>>>>
>> > > >> >>>>>>>> On Tuesday, July 21, 2015 at 6:39:44 AM UTC+8, Yichao
>> > > Yu wrote:
>> > > >> >>>>>>>>>
>> > > >> >>>>>>>>> On Mon, Jul 20, 2015 at 6:35 PM, Brandon Taylor
>> > > >> >>>>>>>>> <brandon....@gmail.com> wrote:
>> > > >> >>>>>>>>> > Ok, a thought, Julia has an inbuilt idea of a
>> > > module. Would it
>> > > >> >>>>>>>>> > be
>> > > >> >>>>>>>>> > possible
>> > > >> >>>>>>>>> > to hijack this functionality to provide pseudo
>> > > -environments?
>> > > >> >>>>>>>>> > That
>> > > >> >>>>>>>>> > is, never
>> > > >> >>>>>>>>> > referring to anything that is not already in an
>> > > explicit
>> > > >> >>>>>>>>> > module?
>> > > >> >>>>>>>>> > And also,
>> > > >> >>>>>>>>> > have a data-frame simply be a module?
>> > > >> >>>>>>>>>
>> > > >> >>>>>>>>> I think this would in principle works. A module is
>> > > basically
>> > > >> >>>>>>>>> what
>> > > >> >>>>>>>>> global scope means so all the performance concern
>> > > applies.
>> > > >> >>>>>>>>>
>> > > >> >>>>>>>>> >
>> > > >> >>>>>>>>> >
>> > > >> >>>>>>>>> > On Friday, July 10, 2015 at 11:31:36 PM UTC+8,
>> > > Brandon Taylor
>> > > >> >>>>>>>>> > wrote:
>> > > >> >>>>>>>>> >>
>> > > >> >>>>>>>>> >> I don't know if you came across the vignette?
>> > > >> >>>>>>>>> >>
>> > > >> >>>>>>>>> >>
>> > > >> >>>>>>>>> >> http://cran.r-project.org/web/packages/lazyeval/vig
>> > > nettes/lazyeval.html ?
>> > > >> >>>>>>>>> >> dplyr uses lazyeval extensively, see
>> > > >> >>>>>>>>> >>
>> > > >> >>>>>>>>> >>
>> > > http://cran.r-project.org/web/packages/dplyr/vignettes/nse.html
>> > > >> >>>>>>>>> >> . The cool
>> > > >> >>>>>>>>> >> thing about being able to incorporate this kind of
>> > > thing in
>> > > >> >>>>>>>>> >> Julia would be
>> > > >> >>>>>>>>> >> being able to use the self-reflection capabilities.
>> > > >> >>>>>>>>> >>
>> > > >> >>>>>>>>> >> On Friday, July 10, 2015 at 10:57:16 AM UTC-4,
>> > > Cedric St-Jean
>> > > >> >>>>>>>>> >> wrote:
>> > > >> >>>>>>>>> >>>
>> > > >> >>>>>>>>> >>>
>> > > >> >>>>>>>>> >>>
>> > > >> >>>>>>>>> >>> On Thursday, July 9, 2015 at 10:35:30 PM UTC-4,
>> > > Brandon
>> > > >> >>>>>>>>> >>> Taylor
>> > > >> >>>>>>>>> >>> wrote:
>> > > >> >>>>>>>>> >>>>
>> > > >> >>>>>>>>> >>>> To walk back in time, you could say something
>> > > like: compile
>> > > >> >>>>>>>>> >>>> this like
>> > > >> >>>>>>>>> >>>> this was is in line 8. Or compile this like this
>> > > was in
>> > > >> >>>>>>>>> >>>> line
>> > > >> >>>>>>>>> >>>> 5. It seems
>> > > >> >>>>>>>>> >>>> like Julia already has some of this functionality
>> > > in
>> > > >> >>>>>>>>> >>>> macros.
>> > > >> >>>>>>>>> >>>> Internal
>> > > >> >>>>>>>>> >>>> variables are compiled as if they were in local
>> > > scope. But
>> > > >> >>>>>>>>> >>>> escaped
>> > > >> >>>>>>>>> >>>> expressions are compiled as if they were in
>> > > global scope.
>> > > >> >>>>>>>>> >>>
>> > > >> >>>>>>>>> >>>
>> > > >> >>>>>>>>> >>> Could you provide context or a real-world use?
>> > > I've looked
>> > > >> >>>>>>>>> >>> at
>> > > >> >>>>>>>>> >>> the
>> > > >> >>>>>>>>> >>> lazyeval package, and I'm not entirely sure what
>> > > it does.
>> > > >> >>>>>>>>> >>> Does
>> > > >> >>>>>>>>> >>> it provide
>> > > >> >>>>>>>>> >>> lazy evaluation for R? That's easy to achieve in
>> > > Julia
>> > > >> >>>>>>>>> >>> (well,
>> > > >> >>>>>>>>> >>> sorta).
>> > > >> >>>>>>>>> >>> Instead of
>> > > >> >>>>>>>>> >>>
>> > > >> >>>>>>>>> >>> d = determinant(matrix)
>> > > >> >>>>>>>>> >>> ....
>> > > >> >>>>>>>>> >>> u = 2 * d
>> > > >> >>>>>>>>> >>>
>> > > >> >>>>>>>>> >>> you can write
>> > > >> >>>>>>>>> >>>
>> > > >> >>>>>>>>> >>> d = ()->determinant(matrix)
>> > > >> >>>>>>>>> >>> ....
>> > > >> >>>>>>>>> >>> u = 2 * d() # determinant is evaluated on use, in
>> > > the
>> > > >> >>>>>>>>> >>> context
>> > > >> >>>>>>>>> >>> where it
>> > > >> >>>>>>>>> >>> was originally defined
>> > > >> >>>>>>>>> >>>
>> > > >> >>>>>>>>> >>> With macros this can turn into
>> > > >> >>>>>>>>> >>>
>> > > >> >>>>>>>>> >>> d = lazy(determinant(matrix))
>> > > >> >>>>>>>>> >>>
>> > > >> >>>>>>>>> >>> which looks nicer (and also can avoid computing
>> > > the
>> > > >> >>>>>>>>> >>> determinant
>> > > >> >>>>>>>>> >>> twice if
>> > > >> >>>>>>>>> >>> d() is called twice).
>> > > >> >>>>>>>>> >>>
>> > > >> >>>>>>>>> >>> Cédric
>> > > >> >>>>>>>>> >>>
>> > > >> >>>>>>>>> >>>>
>> > > >> >>>>>>>>> >>>>
>> > > >> >>>>>>>>> >>>> On Thursday, July 9, 2015 at 9:11:05 PM UTC-4,
>> > > Cedric
>> > > >> >>>>>>>>> >>>> St-Jean
>> > > >> >>>>>>>>> >>>> wrote:
>> > > >> >>>>>>>>> >>>>>
>> > > >> >>>>>>>>> >>>>>
>> > > >> >>>>>>>>> >>>>>
>> > > >> >>>>>>>>> >>>>> On Thursday, July 9, 2015 at 4:14:32 PM UTC-4,
>> > > Brandon
>> > > >> >>>>>>>>> >>>>> Taylor
>> > > >> >>>>>>>>> >>>>> wrote:
>> > > >> >>>>>>>>> >>>>>>
>> > > >> >>>>>>>>> >>>>>> Ok, here's where I'm getting hung up. You said
>> > > that the
>> > > >> >>>>>>>>> >>>>>> compiler
>> > > >> >>>>>>>>> >>>>>> figures out the creation/lifetime of all
>> > > variables at
>> > > >> >>>>>>>>> >>>>>> compile time. So does
>> > > >> >>>>>>>>> >>>>>> that mean there's a list like:
>> > > >> >>>>>>>>> >>>>>>
>> > > >> >>>>>>>>> >>>>>> a maps to location 0 and exists from line 3 to
>> > > line 9
>> > > >> >>>>>>>>> >>>>>> b maps to location 1 and exists from line 7 to
>> > > line 9
>> > > >> >>>>>>>>> >>>>>> a maps to location 10 and exists from line 7 to
>> > > 9?
>> > > >> >>>>>>>>> >>>>>>
>> > > >> >>>>>>>>> >>>>>> and that to map variables to locations on any
>> > > particular
>> > > >> >>>>>>>>> >>>>>> line, the
>> > > >> >>>>>>>>> >>>>>> compiler works its way up the list,
>> > > >> >>>>>>>>> >>>>>
>> > > >> >>>>>>>>> >>>>>
>> > > >> >>>>>>>>> >>>>> Yes, more or less.
>> > > >> >>>>>>>>> >>>>>
>> > > >> >>>>>>>>> >>>>>>
>> > > >> >>>>>>>>> >>>>>>
>> > > >> >>>>>>>>> >>>>>> This is perhaps even more helpful than the
>> > > environment.
>> > > >> >>>>>>>>> >>>>>> The
>> > > >> >>>>>>>>> >>>>>> environment is immediately and completely
>> > > determinable at
>> > > >> >>>>>>>>> >>>>>> any point in the
>> > > >> >>>>>>>>> >>>>>> program. This could make it possible to walk
>> > > back in time
>> > > >> >>>>>>>>> >>>>>> even within the
>> > > >> >>>>>>>>> >>>>>> same scope.
>> > > >> >>>>>>>>> >>>>>
>> > > >> >>>>>>>>> >>>>>
>> > > >> >>>>>>>>> >>>>> Could you expand on what you're thinking of?
>> > > >> >>>>>>>>> >>>>>
>> > > >> >>>>>>>>> >>>>> This kind of compile-time environment could
>> > > conceivably be
>> > > >> >>>>>>>>> >>>>> exposed to
>> > > >> >>>>>>>>> >>>>> macros. Common Lisp had proposals along that
>> > > line
>> > > >> >>>>>>>>> >>>>>
>> > > >> >>>>>>>>> >>>>> (
>> > > https://www.cs.cmu.edu/Groups/AI/html/cltl/clm/node102.html)
>> > > >> >>>>>>>>> >>>>> but as far as
>> > > >> >>>>>>>>> >>>>> I can tell, it was too complicated and not
>> > > useful enough,
>> > > >> >>>>>>>>> >>>>> so
>> > > >> >>>>>>>>> >>>>> it was
>> > > >> >>>>>>>>> >>>>> axed/neutered at some point in the
>> > > standardization
>> > > >> >>>>>>>>> >>>>> process.
>> > > >> >>>>>>>>> >>>>>
>> > > >> >>>>>>>>> >>>>> > Hadley Wickham's lazyeval package in R is
>> > > pretty cool in
>> > > >> >>>>>>>>> >>>>> > that you can
>> > > >> >>>>>>>>> >>>>> > attach an environment to an expression, pass
>> > > it in and
>> > > >> >>>>>>>>> >>>>> > out
>> > > >> >>>>>>>>> >>>>> > of functions with
>> > > >> >>>>>>>>> >>>>> > various modifications, and then evaluate the
>> > > expression
>> > > >> >>>>>>>>> >>>>> > within the original
>> > > >> >>>>>>>>> >>>>> > environment
>> > > >> >>>>>>>>> >>>>>
>> > > >> >>>>>>>>> >>>>> I don't know about R, but to me that sounds
>> > > entirely
>> > > >> >>>>>>>>> >>>>> doable
>> > > >> >>>>>>>>> >>>>> with
>> > > >> >>>>>>>>> >>>>> closures (and macros will give you a nice syntax
>> > > for it)
>> > > >> >>>>>>>>> >>>>>
>> > > >> >>>>>>>>> >>>>>>
>> > > >> >>>>>>>>> >>>>>>
>> > > >> >>>>>>>>> >>>>>> On Wednesday, July 8, 2015 at 8:31:44 PM UTC-4,
>> > > Yichao Yu
>> > > >> >>>>>>>>> >>>>>> wrote:
>> > > >> >>>>>>>>> >>>>>>>
>> > > >> >>>>>>>>> >>>>>>> On Wed, Jul 8, 2015 at 8:23 PM, Yichao Yu
>> > > >> >>>>>>>>> >>>>>>> <yyc...@gmail.com> wrote:
>> > > >> >>>>>>>>> >>>>>>> > On Wed, Jul 8, 2015 at 7:48 PM, Brandon
>> > > Taylor
>> > > >> >>>>>>>>> >>>>>>> > <brandon....@gmail.com> wrote:
>> > > >> >>>>>>>>> >>>>>>> >> Hmm, maybe I'm confused about compilation
>> > > vs
>> > > >> >>>>>>>>> >>>>>>> >> interpretation. Let
>> > > >> >>>>>>>>> >>>>>>> >> me
>> > > >> >>>>>>>>> >>>>>>> >> rephrase. Regardless of a how or when
>> > > statement is
>> > > >> >>>>>>>>> >>>>>>> >> evaluated, it
>> > > >> >>>>>>>>> >>>>>>> >> must have
>> > > >> >>>>>>>>> >>>>>>> >> access at least to its parent environments
>> > > to
>> > > >> >>>>>>>>> >>>>>>> >> successfully resolve
>> > > >> >>>>>>>>> >>>>>>> >> a symbol.
>> > > >> >>>>>>>>> >>>>>>>
>> > > >> >>>>>>>>> >>>>>>> AFAIK, the only scope you can dynamically add
>> > > variable
>> > > >> >>>>>>>>> >>>>>>> to
>> > > >> >>>>>>>>> >>>>>>> is the
>> > > >> >>>>>>>>> >>>>>>> global scope. (This can be done with the
>> > > `global`
>> > > >> >>>>>>>>> >>>>>>> keyword
>> > > >> >>>>>>>>> >>>>>>> or `eval`
>> > > >> >>>>>>>>> >>>>>>> etc). The compiler figure out the
>> > > creation/lifetime of
>> > > >> >>>>>>>>> >>>>>>> all
>> > > >> >>>>>>>>> >>>>>>> local
>> > > >> >>>>>>>>> >>>>>>> variables (at compile time). Therefore, to
>> > > access a
>> > > >> >>>>>>>>> >>>>>>> variable in the
>> > > >> >>>>>>>>> >>>>>>> parent scope:
>> > > >> >>>>>>>>> >>>>>>>
>> > > >> >>>>>>>>> >>>>>>> 1. If it's a global, then it need a runtime
>> > > >> >>>>>>>>> >>>>>>> lookup/binding
>> > > >> >>>>>>>>> >>>>>>> (the
>> > > >> >>>>>>>>> >>>>>>> reason
>> > > >> >>>>>>>>> >>>>>>> global are slow)
>> > > >> >>>>>>>>> >>>>>>> 2. If it's in a parent non-global scope, the
>> > > compiler
>> > > >> >>>>>>>>> >>>>>>> can
>> > > >> >>>>>>>>> >>>>>>> figure out
>> > > >> >>>>>>>>> >>>>>>> how to bind/access it at compile time and no
>> > > extra
>> > > >> >>>>>>>>> >>>>>>> (lookup)
>> > > >> >>>>>>>>> >>>>>>> code at
>> > > >> >>>>>>>>> >>>>>>> runtime is necessary.
>> > > >> >>>>>>>>> >>>>>>>
>> > > >> >>>>>>>>> >>>>>>> >>
>> > > >> >>>>>>>>> >>>>>>> >
>> > > >> >>>>>>>>> >>>>>>> > A julia local variable is basically a
>> > > variable in C.
>> > > >> >>>>>>>>> >>>>>>> > There's a
>> > > >> >>>>>>>>> >>>>>>> > table
>> > > >> >>>>>>>>> >>>>>>> > at compile time to map between symbols and
>> > > stack slots
>> > > >> >>>>>>>>> >>>>>>> > (or
>> > > >> >>>>>>>>> >>>>>>> > whereever
>> > > >> >>>>>>>>> >>>>>>> > they are stored) but such a map does not
>> > > exist at
>> > > >> >>>>>>>>> >>>>>>> > runtime
>> > > >> >>>>>>>>> >>>>>>> > anymore
>> > > >> >>>>>>>>> >>>>>>> > (except for debugging).
>> > > >> >>>>>>>>> >>>>>>> >
>> > > >> >>>>>>>>> >>>>>>> >>
>> > > >> >>>>>>>>> >>>>>>> >> On Wednesday, July 8, 2015 at 7:34:09 PM
>> > > UTC-4,
>> > > >> >>>>>>>>> >>>>>>> >> Brandon
>> > > >> >>>>>>>>> >>>>>>> >> Taylor
>> > > >> >>>>>>>>> >>>>>>> >> wrote:
>> > > >> >>>>>>>>> >>>>>>> >>>
>> > > >> >>>>>>>>> >>>>>>> >>> They must exist at runtime and at local
>> > > scope.
>> > > >> >>>>>>>>> >>>>>>> >>> Evaluating a
>> > > >> >>>>>>>>> >>>>>>> >>> symbol is
>> > > >> >>>>>>>>> >>>>>>> >>> impossible without a pool of defined
>> > > symbols in
>> > > >> >>>>>>>>> >>>>>>> >>> various
>> > > >> >>>>>>>>> >>>>>>> >>> scopes to
>> > > >> >>>>>>>>> >>>>>>> >>> match it
>> > > >> >>>>>>>>> >>>>>>> >>> to. Unless I'm missing something?
>> > > >> >>>>>>>>> >>>>>>> >>>
>> > > >> >>>>>>>>> >>>>>>> >>> On Wednesday, July 8, 2015 at 7:26:27 PM
>> > > UTC-4,
>> > > >> >>>>>>>>> >>>>>>> >>> Jameson
>> > > >> >>>>>>>>> >>>>>>> >>> wrote:
>> > > >> >>>>>>>>> >>>>>>> >>>>
>> > > >> >>>>>>>>> >>>>>>> >>>> There are global symbol tables for static
>> > > analysis
>> > > >> >>>>>>>>> >>>>>>> >>>> /
>> > > >> >>>>>>>>> >>>>>>> >>>> reflection,
>> > > >> >>>>>>>>> >>>>>>> >>>> but they
>> > > >> >>>>>>>>> >>>>>>> >>>> do not exist at runtime or for the local
>> > > scope.
>> > > >> >>>>>>>>> >>>>>>> >>>>
>> > > >> >>>>>>>>> >>>>>>> >>>> On Wed, Jul 8, 2015 at 7:06 PM Brandon
>> > > Taylor
>> > > >> >>>>>>>>> >>>>>>> >>>> <brandon....@gmail.com>
>> > > >> >>>>>>>>> >>>>>>> >>>> wrote:
>> > > >> >>>>>>>>> >>>>>>> >>>>>
>> > > >> >>>>>>>>> >>>>>>> >>>>> Surely environments already exist
>> > > somewhere inside
>> > > >> >>>>>>>>> >>>>>>> >>>>> Julia? How
>> > > >> >>>>>>>>> >>>>>>> >>>>> else could
>> > > >> >>>>>>>>> >>>>>>> >>>>> you keep track of scope? It would be
>> > > simply a
>> > > >> >>>>>>>>> >>>>>>> >>>>> matter
>> > > >> >>>>>>>>> >>>>>>> >>>>> of
>> > > >> >>>>>>>>> >>>>>>> >>>>> granting users
>> > > >> >>>>>>>>> >>>>>>> >>>>> access to them. Symbol tables in a
>> > > mutable
>> > > >> >>>>>>>>> >>>>>>> >>>>> language
>> > > >> >>>>>>>>> >>>>>>> >>>>> are by
>> > > >> >>>>>>>>> >>>>>>> >>>>> default mutable.
>> > > >> >>>>>>>>> >>>>>>> >>>>> It would certainly be possible only give
>> > > users
>> > > >> >>>>>>>>> >>>>>>> >>>>> access
>> > > >> >>>>>>>>> >>>>>>> >>>>> to
>> > > >> >>>>>>>>> >>>>>>> >>>>> immutable
>> > > >> >>>>>>>>> >>>>>>> >>>>> reifications (which could solve a bunch
>> > > of
>> > > >> >>>>>>>>> >>>>>>> >>>>> problems
>> > > >> >>>>>>>>> >>>>>>> >>>>> as is).
>> > > >> >>>>>>>>> >>>>>>> >>>>> However, it
>> > > >> >>>>>>>>> >>>>>>> >>>>> seems natural to match mutable symbol
>> > > tables with
>> > > >> >>>>>>>>> >>>>>>> >>>>> mutable
>> > > >> >>>>>>>>> >>>>>>> >>>>> reifications, and
>> > > >> >>>>>>>>> >>>>>>> >>>>> immutable symbol tables with immutable
>> > > >> >>>>>>>>> >>>>>>> >>>>> reifications.
>> > > >> >>>>>>>>> >>>>>>> >>>>>
>> > > >> >>>>>>>>> >>>>>>> >>>>>
>> > > >> >>>>>>>>> >>>>>>> >>>>> On Wednesday, July 8, 2015 at 6:50:03 PM
>> > > UTC-4,
>> > > >> >>>>>>>>> >>>>>>> >>>>> Brandon Taylor
>> > > >> >>>>>>>>> >>>>>>> >>>>> wrote:
>> > > >> >>>>>>>>> >>>>>>> >>>>>>
>> > > >> >>>>>>>>> >>>>>>> >>>>>> I'm not sure I understand...
>> > > >> >>>>>>>>> >>>>>>> >>>>>>
>> > > >> >>>>>>>>> >>>>>>> >>>>>> On Wednesday, July 8, 2015 at 6:24:37
>> > > PM UTC-4,
>> > > >> >>>>>>>>> >>>>>>> >>>>>> John
>> > > >> >>>>>>>>> >>>>>>> >>>>>> Myles
>> > > >> >>>>>>>>> >>>>>>> >>>>>> White wrote:
>> > > >> >>>>>>>>> >>>>>>> >>>>>>>
>> > > >> >>>>>>>>> >>>>>>> >>>>>>> Reified scope makes static analysis
>> > > much too
>> > > >> >>>>>>>>> >>>>>>> >>>>>>> hard.
>> > > >> >>>>>>>>> >>>>>>> >>>>>>> Take any
>> > > >> >>>>>>>>> >>>>>>> >>>>>>> criticism
>> > > >> >>>>>>>>> >>>>>>> >>>>>>> of mutable state: they all apply to
>> > > globally
>> > > >> >>>>>>>>> >>>>>>> >>>>>>> mutable symbol
>> > > >> >>>>>>>>> >>>>>>> >>>>>>> tables.
>> > > >> >>>>>>>>> >>>>>>> >>>>>>>
>> > > >> >>>>>>>>> >>>>>>> >>>>>>> On Wednesday, July 8, 2015 at 10:26:23
>> > > PM UTC+2,
>> > > >> >>>>>>>>> >>>>>>> >>>>>>> Milan
>> > > >> >>>>>>>>> >>>>>>> >>>>>>> Bouchet-Valat
>> > > >> >>>>>>>>> >>>>>>> >>>>>>> wrote:
>> > > >> >>>>>>>>> >>>>>>> >>>>>>>>
>> > > >> >>>>>>>>> >>>>>>> >>>>>>>> Le mercredi 08 juillet 2015 à 13:20
>> > > -0700,
>> > > >> >>>>>>>>> >>>>>>> >>>>>>>> Brandon
>> > > >> >>>>>>>>> >>>>>>> >>>>>>>> Taylor a
>> > > >> >>>>>>>>> >>>>>>> >>>>>>>> écrit :
>> > > >> >>>>>>>>> >>>>>>> >>>>>>>> > All functions.
>> > > >> >>>>>>>>> >>>>>>> >>>>>>>> Well, I don't know of any language
>> > > which
>> > > >> >>>>>>>>> >>>>>>> >>>>>>>> doesn't
>> > > >> >>>>>>>>> >>>>>>> >>>>>>>> have
>> > > >> >>>>>>>>> >>>>>>> >>>>>>>> scoping
>> > > >> >>>>>>>>> >>>>>>> >>>>>>>> rules...
>> > > >> >>>>>>>>> >>>>>>> >>>>>>>>
>> > > >> >>>>>>>>> >>>>>>> >>>>>>>> Anyway, I didn't say scoping rules
>> > > are
>> > > >> >>>>>>>>> >>>>>>> >>>>>>>> necessarily
>> > > >> >>>>>>>>> >>>>>>> >>>>>>>> confusing, I was
>> > > >> >>>>>>>>> >>>>>>> >>>>>>>> only referring to R formulas. But
>> > > according to
>> > > >> >>>>>>>>> >>>>>>> >>>>>>>> the
>> > > >> >>>>>>>>> >>>>>>> >>>>>>>> examples
>> > > >> >>>>>>>>> >>>>>>> >>>>>>>> you
>> > > >> >>>>>>>>> >>>>>>> >>>>>>>> posted,
>> > > >> >>>>>>>>> >>>>>>> >>>>>>>> your question appears to be
>> > > different.
>> > > >> >>>>>>>>> >>>>>>> >>>>>>>>
>> > > >> >>>>>>>>> >>>>>>> >>>>>>>>
>>
>

Reply via email to