Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Isn't there a nicer way to combine multiple `Union{T, Nothing}`

I'm very new to Julia but I've got a some background in Scheme/Rust/F#.

Today I wanted to make yesterday's AoC nicer without an explicit number of nested loops.

I arrived at this working solution, but I don't like the last if. In the languages mentioned above I would call a function (or use a computation expression) that gives me the first result that is not None. For Julia, I expected something to do that. It does, but unexpectedly in an eager fashion.

So When I tried return something(find(r, n, start + 1, which), find(r, n - 1, start + 1, extended)), that also evaluated the second argument when the first already had a result—and thus crashed.

Is there a macro/lazy version or something that I didn't find? How are you supposed to handle a case like that?

I also thought about (short-circuited) or'ing them together, but I guess Julia's strictness in that matter spoils that.

using DataStructures

function find(r::Array{Int}, n, start = 1, which = nil())::Union{Int,Nothing}
    if start <= length(r)
        extended = cons(start, which)
        with_current = sum(i -> r[i], extended)
        if with_current == 2020 && n == 1
            return prod(i -> r[i], extended)
        else
            # Unfortunately no :(
            #return something(find(r, n, start + 1, which), find(r, n - 1, start + 1, extended))
            re = find(r, n, start + 1, which)
            if isnothing(re)
                return find(r, n - 1, start + 1, extended)
            else
                re
            end
        end
    end
end
like image 467
primfaktor Avatar asked Dec 02 '20 14:12

primfaktor


People also ask

Can multiple columns be added to a union query?

Msg 205, Level 16, State 1, Line 2 All queries combined using a UNION, INTERSECT or EXCEPT operator must have an equal number of expressions in their target lists. An additional column would have to be caught in the remaining queries (NULL AS [Cluster]). Different column names are not a problem.

What is the difference between join and Union in SQL?

Simply put, JOINs combine data by appending the columns from one table alongside the columns from another table. In contrast, UNIONs combine data by appending the rows alongside the rows from another table. So, if we want to generate a combined list of the supplier IDs from the tables wine and main_course, we can use the following SQL query:

Is there an alternative to Union?

Then the answer is "no", there isn't an alternative. UNION and UNION ALL fulfil specific functions. Even functions that fulfil similar roles are often different in some way. For example, ISNULL and COALESCE are often thought to be the very similar (or the same when using 2 parameters), but this really isn't the case.

Is it possible to combine multiple tables into one large table?

Combining several tables to one large table is possible in all 3 ways. As we have seen, the behavior of UNION in SQL Server and UNION in DAX within Power BI is very similar. Here tables with the same number of columns are placed directly under each other.


1 Answers

Let me comment more on it why it is not possible given the discussion in the comments.

In Julia function arguments are evaluated eagerly, so Julia evaluates both find(r, n, start + 1, which) and find(r, n - 1, start + 1, extended) before passing them to something function.

Now, with macros you have (I am not writing in a fully general case for simplicity and I hope I got the hygiene right :)):

julia> macro something(x, y)
           quote
               local vx = $(esc(x))
               isnothing(vx) ? $(esc(y)) : vx
           end
       end
@something (macro with 1 method)

julia> @something 1 2
1

julia> @something nothing 2
2

julia> @something 1 sqrt(-1)
1

julia> @something nothing sqrt(-1)
ERROR: DomainError with -1.0:
sqrt will only return a complex result if called with a complex argument. Try sqrt(Complex(x)).

(in a full-blown version of the macro varargs and Some should be handled to replicate something exactly)

like image 72
Bogumił Kamiński Avatar answered Oct 16 '22 19:10

Bogumił Kamiński