Elixir #spec annotation for atoms - functional-programming

The function below is written in Elixir:
def count(:comments, id), do 0
When I want to get its documentation using 'h' in iex, this is printed out:
iex> h Module.count
def count(atom, id)
But I want ':comments' to appear on the documentation using 'h'.
iex> h Module.count
def count(:comments, id)
How can I do that?
Thanks in advance!

You want to declare the function with a bodyless clause. See the Elixir docs on documenting function arguments, or the Writing Documentation doc as a whole.
EDIT:
Looking at it further, while it's not exactly what you're looking for adding
#doc"""
count(:comments, id)
"""
before your function definition will get you closer to what you're looking for.

Related

Creating custom types in Julia

In Julia, how do I create custom types MyOrderedDictA and MyOrderedDictB such that:
Each has all the functionality of an OrderdDict, and can be passed to any function that accepts AbstractDicts
They are distinct from each other, so that I can take advantage of multiple dispatch.
I suspect\hope this is straightforward, but haven’t been able to figure it out.
Basically, what you have to do is to define your type MyOrderedDictA, wrapping a regular OrderedDict, and forward all functions that one can apply to an OrderedDict to this wrapped dict.
Unfortunately, the AbstractDict interface is (to my knowledge) currently not documented (cf. AbstractArray). You could look at their definition and check which functions are defined for them. Alternatively, there is the more practical approach to just use your MyOrderedDictA and whenever you get an error message, because a function is not defined, you forward this function "on-the-fly".
In any case, using the macro #forward from Lazy.jl you can do something along the lines of the following.
using Lazy
struct MyOrderedDictA{T,S} <: AbstractDict{T,S}
dict::OrderedDict{T,S}
end
MyOrderedDictA{T,S}(args...; kwargs...) where {T,S} = new{T,S}(OrderedDict{T,S}(args...; kwargs...))
function MyOrderedDictA(args...; kwargs...)
d = OrderedDict(args...; kwargs...)
MyOrderedDictA{keytype(d),valtype(d)}(d)
end
#forward MyOrderedDictA.dict (Base.length, Base.iterate, Base.getindex, Base.setindex!)
d = MyOrderedDictA(2=>1, 1=>2)
Others will be better placed to answer this, but a quick take:
For this you will need to look at the OrderedDict implementation, and specifically which methods are defined for OrderedDicts. If you want to be able to pass it to methods accepting AbstractDicts you need to subtype it like struct MyDictA{T, S} <: AbstractDict{T, S}
If you define two structs they will automatically be discting from each other!? (I might be misunderstanding the question here)

How to display the definition of a function

This is probably a newbie question... but is it possible to show the definition of a (user defined) function? While debugging/optimizing it is convenient to quickly see how a certain function was programmed.
Thanks in advance.
You can use the #edit macro, which is supposed to take you to the definition of a method, similarly to how the #which macro which shows the file and line # where that particular method was defined, for example:
julia> #which push!(CDFBuf(),"foo")
push!{T<:CDF.CDFBuf}(buff::T, x) at /d/base/DA/DA.jl:105
julia> #which search("foobar","foo")
search(s::AbstractString, t::AbstractString) at strings/search.jl:146
Note that methods that are part of Julia will show a path relative to the julia source directory "base".
While this is not an automatic feature available with Julia in general (as pointed out by Stefan), if you add docstrings when you define your initial function, you can always use the help?> prompt to query this docstring. For example
julia> """mytestfunction(a::Int, b)""" function mytestfunction(a::Int, b)
return true
This attaches the docstring "mytestfunction(a::Int, b)" to the function mytestfunction(a::Int, b). Once this is defined, you can then use the Julia help prompt (by typing ? at the REPL), to query this documentation.
help?> mytestfunction
mytestfunction(a::Int, b)

How to call two functions and use their results as arguments for each other?

I have code:
let join a ~with':b ~by:key =
let rec a' = link a ~to':b' ~by:key
and b' = link b ~to':a' ~by:(Key.opposite key) in
a'
and compilation result for it is:
Error: This kind of expression is not allowed as right-hand side of
`let rec' build complete
I can rewrite it to:
let join a ~with':b ~by:key =
let rec a'() = link a ~to':(b'()) ~by:key
and b'() = link b ~to':(a'()) ~by:(Key.opposite key) in
a'()
It is compilable variant, but implemented function is infinitely recursive and it is not what I need.
My questions: Why is first implementation invalid? How to call two functions and use their results as arguments for each other?
My compiler version = 4.01.0
The answer to your first question is given in Section 7.3 of the OCaml manual. Here's what it says:
Informally, the class of accepted definitions consists of those definitions where the defined names occur only inside function bodies or as argument to a data constructor.
Your names appear as function arguments, which isn't supported.
I suspect the reason is that you can't assign a semantics otherwise. It seems to me the infinite computation that you see is impossible to avoid in general.

Returning multiple values in Ruby, to be used to call a function

Is it possible to return multiple values from a function?
I want to pass the return values into another function, and I wonder if I can avoid having to explode the array into multiple values
My problem?
I am upgrading Capybara for my project, and I realized, thanks to CSS 'contains' selector & upgrade of Capybara, that the statement below will no longer work
has_selector?(:css, "#rightCol:contains(\"#{page_name}\")")
I want to get it working with minimum effort (there are a lot of such cases), So I came up with the idea of using Nokogiri to convert the css to xpath. I wanted to write it so that the above function can become
has_selector? xpath(:css, "#rightCol:contains(\"#{page_name}\")")
But since xpath has to return an array, I need to actually write this
has_selector?(*xpath(:css, "#rightCol:contains(\"#{page_name}\")"))
Is there a way to get the former behavior?
It can be assumed that right now xpath func is like the below, for brevity.
def xpath(*a)
[1, 2]
end
You cannot let a method return multiple values. In order to do what you want, you have to change has_selector?, maybe something like this:
alias old_has_selector? :has_selector?
def has_selector? arg
case arg
when Array then old_has_selector?(*arg)
else old_has_selector?(arg)
end
end
Ruby has limited support for returning multiple values from a function. In particular a returned Array will get "destructured" when assigning to multiple variables:
def foo
[1, 2]
end
a, b = foo
a #=> 1
b #=> 2
However in your case you need the splat (*) to make it clear you're not just passing the array as the first argument.
If you want a cleaner syntax, why not just write your own wrapper:
def has_xpath?(xp)
has_selector?(*xpath(:css, xp))
end

Is there a nice idiom for adding a new list or appending to a list (if present) in a dictionary?

This is the second time I've implemented something like this and I suspect there has to be a better (read: more pythonic) way to do this:
phone_book = {}
def add_number(name,number):
if name in phone_book:
phone_book['name'].append(number)
else:
phone_book['name'] = [number]
I realize the code can likely be made more concise with conditional assignments, but I suspect there's likely a better way to go about this. I'm not interested in only making the code shorter.
Yep, you can use defaultdict. With this dict subclass, when you access an element in the dictionary, if a value doesn't already exist, it automatically creates one using a constructor function you specify.
from collections import defaultdict
phone_book = defaultdict(list)
def add_number(name, number):
phone_book[name].append(number)
Use dict's setdefault like this:
phone_book.setdefault('name', []).append(number)

Resources