* open(...) do ... end * comes from Ruby, but I agree it can be confusing 
if you're not already familiar with the construct.

On Monday, April 28, 2014 6:06:37 PM UTC+2, Simon Byrne wrote:
>
> On Monday, 28 April 2014 16:47:12 UTC+1, Stefan Karpinski wrote:
>>
>> It's odd to me that this is an issue because this is possibly the least 
>> deep feature of the language – it's literally just a way to put parentheses 
>> in less awkward places. But if Ruby's do blocks have any lesson to teach, 
>> it's that this relatively small syntax change can make higher order 
>> programming appealing and common, rather than niche.
>>
>
> My own perspective is that this is due to two reasons
>
> 1) `do` is the only (non-macro) construction that rewrites expressions i.e.
>
> open("outfile", "w") do f
>   write(f, data)
> end
>
> does not (directly at least) call the method `open("outfile", "w")`
>
> 2) In the case of `open` in particular, it is an exception to the general 
> duck typing behaviour that methods should have broadly consistent behaviour 
> with different arguments. Perhaps this would be less confusing if it was 
> called `withfile` or something similar?
>
>
>
>
>>
>> On Mon, Apr 28, 2014 at 6:43 AM, Tim Holy <[email protected]> wrote:
>>
>>> The "do" block syntax was for me one of the more difficult aspects of 
>>> Julia's
>>> syntax to wrap my head around, although now I use it frequently. I just
>>> expanded this section of the manual, trying to incorporate elements of 
>>> this
>>> discussion.
>>>
>>> --Tim
>>>
>>> On Monday, April 28, 2014 12:57:23 AM Peter Simon wrote:
>>> > Going back and rereading the 'open' documentation,  it clearly states 
>>> that
>>> > the method taking a function as its first argument will apply that 
>>> function
>>> > to the file handle returned by the method without the handle.   Thanks 
>>> for
>>> > your patience.
>>> >
>>> > On Apr 27, 2014 9:41 PM, "Peter Simon" <[email protected]> wrote:
>>> > > Ah, you just switched on the light for me.  I thought that the 
>>> example was
>>> > > illustrating a general principle, but in fact the essential feature
>>> > > depends
>>> > > on knowledge of the way that the 'open' method is coded.
>>> > >
>>> > > Thanks!
>>> > >
>>> > > On Apr 27, 2014 9:24 PM, "Amit Murthy" <[email protected]> wrote:
>>> > >> The actual function as defined in base/io.jl
>>> > >>
>>> > >> function open(f::Function, args...)
>>> > >>
>>> > >>     io = open(args...)
>>> > >>     try
>>> > >>
>>> > >>         f(io)
>>> > >>
>>> > >>     finally
>>> > >>
>>> > >>         close(io)
>>> > >>
>>> > >>     end
>>> > >>
>>> > >> end
>>> > >>
>>> > >> Just multiple dispatch at work. The 'open' variant without a file 
>>> handle
>>> > >> is called first.
>>> > >>
>>> > >> On Mon, Apr 28, 2014 at 9:44 AM, Peter Simon <[email protected]
>>> >wrote:
>>> > >>> Right, I don't have a problem with that.  I simply used "inner" as 
>>> a way
>>> > >>> to refer to the function that is used as the first argument to the 
>>> other
>>> > >>> ("outer") function.  Sorry if I abused a conventional meaning of 
>>> these
>>> > >>> terms.
>>> > >>>
>>> > >>> I would like to know how this anonymous function (in the "open" 
>>> example)
>>> > >>> is passed the file handle.  My confusion stems from the fact that 
>>> this
>>> > >>> handle, to my knowledge, is not available until the "open" function
>>> > >>> provides it as its return value.
>>> > >>>
>>> > >>> On Sunday, April 27, 2014 8:59:50 PM UTC-7, Amit Murthy wrote:
>>> > >>>> It is just a way to define an anonymous function. It is not a way 
>>> to
>>> > >>>> define an "inner" function in that sense.
>>> > >>>>
>>> > >>>> On Mon, Apr 28, 2014 at 9:24 AM, Peter Simon <[email protected]
>>> >wrote:
>>> > >>>>> My question concerns where this handle comes from.  Isn't the 
>>> handle
>>> > >>>>> coming from the output of 'open'?  Since 'open' is the "outer"
>>> > >>>>> function of
>>> > >>>>> the 'do' construct, then why doesn't the outer function in the 
>>> first
>>> > >>>>> example also supply its output as input to its inner function?
>>> > >>>>>
>>> > >>>>> On Sunday, April 27, 2014 8:40:27 PM UTC-7, Amit Murthy wrote:
>>> > >>>>>> Without using a do-block, you would need to pass in a function 
>>> as the
>>> > >>>>>> first argument to 'map'.
>>> > >>>>>> 'open' has a variant where the first argument is again a 
>>> function
>>> > >>>>>> that accepts an open handle.
>>> > >>>>>>
>>> > >>>>>> The do-block syntax in this case just allows you to define the 
>>> said
>>> > >>>>>> function.
>>> > >>>>>>
>>> > >>>>>> On Mon, Apr 28, 2014 at 8:55 AM, Peter Simon
>>> <[email protected]>wrote:
>>> > >>>>>>> In the Julia manual, the second example in
>>> > >>>>>>> block-syntax-for-function-arguments<
>>> http://docs.julialang.org/en/lat
>>> > >>>>>>> est/manual/functions/#block-syntax-for-function-arguments>
>>> contains>>>>>>>
>>> > >>>>>>> the following do block:
>>> > >>>>>>>     open("outfile", "w") do f
>>> > >>>>>>>
>>> > >>>>>>>         write(f, data)
>>> > >>>>>>>
>>> > >>>>>>>     end
>>> > >>>>>>>
>>> > >>>>>>> and the documentation states that "The function argument to 
>>> open
>>> > >>>>>>> receives a handle to the opened file."  I conclude from this 
>>> that
>>> > >>>>>>> the return value (i.e., the file handle) of the open function 
>>> is
>>> > >>>>>>> passed to this function f -> write(f, data) that is used as the
>>> > >>>>>>> first argument of open.  So far, so good (I think).  But now I 
>>> go
>>> > >>>>>>> back and take another look at the first do block example:
>>> > >>>>>>>
>>> > >>>>>>> map([A, B, C]) do x
>>> > >>>>>>>
>>> > >>>>>>>     if x < 0 && iseven(x)
>>> > >>>>>>>
>>> > >>>>>>>         return 0
>>> > >>>>>>>
>>> > >>>>>>>     elseif x == 0
>>> > >>>>>>>
>>> > >>>>>>>         return 1
>>> > >>>>>>>
>>> > >>>>>>>     else
>>> > >>>>>>>
>>> > >>>>>>>         return x
>>> > >>>>>>>
>>> > >>>>>>>     endend
>>> > >>>>>>>
>>> > >>>>>>> I try to interpret this example in light of what I learned 
>>> from the
>>> > >>>>>>> second example.  The map function has a return value, 
>>> consisting of
>>> > >>>>>>> the array [A, B, C], modified by applying the function in the 
>>> do
>>> > >>>>>>> block to each element.  If this example behaved like in the 
>>> second
>>> > >>>>>>> example, then the output of the map function should be passed 
>>> as an
>>> > >>>>>>> input to the function defined in the do block.  Clearly this
>>> > >>>>>>> doesn't happen, so the lesson I learned from the second example
>>> > >>>>>>> doesn't apply here, apparently.  Why not?  Under what 
>>> conditions is
>>> > >>>>>>> the output of the outer function passed as an input to the 
>>> inner
>>> > >>>>>>> function?
>>> > >>>>>>>
>>> > >>>>>>> I must be looking at this wrong and would appreciate some help 
>>> in
>>> > >>>>>>> getting my mind right :-).
>>> > >>>>>>>
>>> > >>>>>>>
>>> > >>>>>>> Thanks,
>>> > >>>>>>>
>>> > >>>>>>> Peter
>>>
>>
>>

Reply via email to