Partial Function Application In Elixir

So I’m trying to fill out my understanding of basic functional programming concepts in terms of Elixir and Erlang.  One concept that I wanted to know a bit more about is how Partial Function Application and Currying work in Elixir.  Especially given that the function signature of a function in Elixir includes its arity, it seems somewhat unlikely that Elixir would support currying and/or partial function application.  But a little bit of hacking turned up a nice surprise.  While Elixir may not support currying (I really cannot tell if it is supported or not) it does support partial function application which seems to be the main reason to concern one’s self with currying anyway.

Partial Function Application With Lambdas


multiply = &(&1 * &2)

timestwo = &(multiply.(&1,2))

Interestingly, using this technique you can set any number of parameters to a fixed value.  Consider this:


multiply4 = &(&1 * &2 * &3 * &4)

times20 = &(multiply4.(&1,&2,5,4))

Lest I be misunderstood, I wouldn’t advocate writing code like that; I’m just saying that it’s possible to do.

Partial Function Application With Modules


defmodule PaTest do
  def f1(n, m) do
    n * m
  end

  def f2(m) do
    f1(3,m)
  end
end

I hope this may save someone a bit of work.

Calling A Database Stored Proc Via ODBC From Elixir

This took me a while to figure out so I’m hoping that by posting this, it’ll save others some work. I’ve got a legacy system that I’m working with; one of the initiatives I’ve been pursuing in my spare time is to build a JSON API to wrap this legacy database so that other developers within the firm can get at the data with JSON calls.  It’s not a high-priority to get this done which makes it a great candidate for exactly this sort of thing because I can work on it at my own pace and I don’t have to cut too many corners. This legacy system was pretty well-designed (kudos to the original developers) and one thing they did was to build stored procs to get data from the DB.  So as I’m building out this new API, I also need to call those stored procs; this way I don’t inadvertently miss any logic that is built into the SP’s. The issue I had was trying to figure out how to call a stored proc from Elixir.  I can find examples of calling a parameterized query from Erlang and I can find a few places where people have documented using parameterized queries to call a stored proc with ODBC but I couldn’t quite get the two ideas working together. I made up a dummy SP because I was trying to avoid additional needless complication while I’m trying to figure this out.  So here’s my dummy SP:


CREATE PROCEDURE [dbo].[usp_CheckName] @NameToCheck VARCHAR(100) AS
SELECT DomainName FROM tnm_validdomains WHERE DomainName = @NameToCheck

Anyone familiar with stored procs can see this is about as simple as a stored proc could be.

So this is where it gets a little bit interesting.  First the ODBC code is an Erlang library.  As someone else pointed out, you have to be careful about the difference between Erlang’s list of chars vs. Elixir’s strings–this comes up in this code.


#Test calling SP from Elixir

:odbc.start()
{:ok,_ref} = :odbc.connect('Driver={SQL Server};Server=(local);Database=TNM;Trusted_Connection=True;',[])
spstmt = '{CALL usp_CheckName (?)}' #Call Stored Proc Statement
testval = "GETBACKSTITCH.COM"
{:selected,field_list,_result} = :odbc.param_query(_ref,spstmt,[{{:sql_varchar,100}, [to_char_list(testval)]}])
IO.puts("Fields returned: #{field_list}")
IO.inspect(_result) #Note; in this case _result is a binary not a string.
:odbc.stop()

Couple of things I’d like to call out here:

1.) Note well the line I’ve commented as the “Call Stored Proc Statement” line. I don’t believe I found any reference to passing a “CALL” statement to a param_query in Erlang–anywhere.  Of course my GoogleFu may have failed me.  But the real trick to be aware of here is the need for the literal curly braces at the start and end of the string.  I spent hours with spstmt = ‘CALL usp_CheckName(?)}’ and the error seemed to indicate that the problem was the value that I was passing at the parameter.  I finally spotted the problem by accident in someone’s PHP code sample of all places.

At any rate, that same trick about “{CALL (?)}” is needed in Erlang and Elixir too.

2.) That last parameter to the param_query function is a bit interesting.  It’s a list of tuples of tuples and lists.  Parsing it a bit more finely:

[                                             #List
  {                                           # Of Tuples
    {:sql_varchar,100} ,                      # Of an ODBC Type Tuple
    [to_char_list(testval)]                   # And a list of the values 
                                              # to substitute for the parameters.
  } 
]

I hope this helps anyone else who’s trying to figure out how to code a call to a stored proc from either Erlang or Elixir.