Steve,

The error you're seeing is because `@inbounds elseif a[1] <= 0` is not a
valid expression by itself. You still have to remember that `@inbounds` is
a macro, so the next valid expression after `@inbounds` is passed as the
argument to it. If you try to pass an incomplete expression (as in
`elseif`), it will have an error. As I mentioned in my previous email, you
can achieve multiline no-bounds-checking by using `@inbounds begin ...
end`. So your example above would be:

function sqrtfirst{T}(a::Array{T, 1})
    @assert(size(a,1) >= 1)
    @inbounds begin
     if a[1] > 0
         p = sqrt(a[1])
     elseif a[1] <= 0
         p = sqrt(-a[1])
     end
     end
    p
end

The usage of `@inbounds` may indeed be a bit finicky, but it at least
provides the ability to turn off bounds-checking. There was also talk of
being able to run an entire script/program with bounds-checking turned off,
which will probably be more of an option when static compilation is done.

-Jacob


On Mon, Aug 4, 2014 at 2:23 PM, <[email protected]> wrote:

> Jacob,
>
> Here's another gotcha: It's ok to put @inbounds before if but not elseif.
>  For example, this works:
>
> function sqrtfirst{T}(a::Array{T, 1})
>     @assert(size(a,1) >= 1)
>     @inbounds if a[1] > 0
>         @inbounds p = sqrt(a[1])
>     elseif a[1] <= 0
>         @inbounds p = sqrt(-a[1])
>     end
>     p
> end
>
> but this gives an error
>
> function sqrtfirst{T}(a::Array{T, 1})
>     @assert(size(a,1) >= 1)
>     @inbounds if a[1] > 0
>         @inbounds p = sqrt(a[1])
>     @inbounds elseif a[1] <= 0
>         @inbounds p = sqrt(-a[1])
>     end
>     p
> end
>
> I am a reasonably experienced programmer in Matlab and C++, but I am
> having a tough time figuring out this syntax. I would say that a language
> feature this difficult to understand should be deprecated and replaced with
> something simpler.
>
> -- Steve Vavasis
>
>
>
> On Monday, August 4, 2014 1:45:21 PM UTC-4, [email protected] wrote:
>>
>> Dear Julia users,
>>
>> The usage of the @inbounds macro is not explained the manual, and its
>> syntax appears to be strange.  Consider the three functions at the end of
>> this posting.  Only the third one works -- why?
>>
>> In general, I think @inbounds is broken.  Besides the weird syntax, it
>> has two other issues.  First, there is no way to apply the macro to one
>> subscript operation but not another in a long expression (as far as I
>> know).  Second, it is not extensible in the sense that if programmer A
>> implements his/her own array-like structure with his/her own getindex and
>> setindex operations, he/she might like to have two versions of
>> getindex/setindex, one safe/slower and the other unsafe/faster, but there
>> is no way for programmer A to detect whether user B, a user of his/her new
>> array-like structure, has requested @inbounds or not.
>>
>> I would like to propose the following replacement for @inbounds, which
>> solves all three problems.  Instead of a macro, there should be two
>> different subscript operations, say a[1] and a[$ 1 $], where the first is
>> safe/slow and the second is unsafe/fast.  The compiler will compile the
>> first as getindex/setindex and the second as getindexUnsafe/setindexUnsafe.
>>
>> -- Steve Vavasis
>>
>>
>>
>> function sqrtfirst{T}(a::Array{T, 1})
>>     @assert(size(a,1) >= 1)
>>     @inbounds sqrt(a[1])
>> end
>>
>> function sqrtfirst{T}(a::Array{T, 1})
>>     @assert(size(a,1) >= 1)
>>     return @inbounds sqrt(a[1])
>> end
>>
>> function sqrtfirst{T}(a::Array{T, 1})
>>     @assert(size(a,1) >= 1)
>>     @inbounds return sqrt(a[1])
>> end
>>
>>
>>
>>

Reply via email to