I know one can use pattern matching to extract the head and tail from a list. But is that necessary? There's nothing called head or tail in the lists module, and erl. (It does include nth/2 and nthtail/2, which are more powerful, but those seem like unnaturally verbose ways to achieve head and tail.)
I'm not finding them in the top namespace either:
Erlang/OTP 24 [erts-12.0] [source] [64-bit] [smp:4:4] [ds:4:4:10] [async-threads:1] [jit]
Eshell V12.0 (abort with ^G)
1> head([1,2]).
** exception error: undefined shell command head/1
2> tail([1,2]).
** exception error: undefined shell command tail/1
Pattern matching is the recommended way to access head and tail in lists. Code using functions to access them too often probably is not very good idiomatic Erlang. Nevertheless, in rare occasions the functions are indeed useful. You can find them among other Erlang Built In Functions at this link under the names hd and tl.
Pattern Matching is a standard way in functional programming languages to operate over data, and Erlang is no exception. Hence exists a way to deal with Lists as well. And then again, List being a native/built-in/primitive type, available are those hd and tl BIF(s) to operate over them.
Related
I've been learning Clojure and am a good way through a book on it when I realized how much I'm still struggling to interpret the code. What I'm looking for is the abstract structure, interface, or rules, Clojure uses to parse code. I think it looks something like:
(some-operation optional-args)
optional-args can be nearly anything and that's where I start getting confused.
(operation optional-name-string [vector of optional args]) would equal (defn newfn [argA, argB])
I think this pattern holds for all lists () but with so much flexibility and variation in Clojure, I'm not sure. It would be really helpful to see the rules the interpreter follows.
You are not crazy. Sure it's easy to point out how "easy" ("simple"? but that another discussion) Clojure syntax is but there are two things for a new learner to be aware of that are not pointed out very clearly in beginning tutorials that greatly complicate understanding what you are seeing:
Destructuring. Spend some quality time with guides on destructuring in Clojure. I will say that this adds a complexity to the language and is not dissimilar from "*args" and "**kwargs" arguments in Python or from the use of the "..." spread operator in javascript. They are all complicated enough to require some dedicated time to read. This relates to the optional-args you reference above.
macros and metaprogramming. In the some-operation you reference above, you wish to "see the rules the interpreter follows". In the majority of the cases it is a function but Clojure provides you no indication of whether you are looking at a function or a macro. In the standard library, you will just need to know some standard macros and how they affect the syntax they headline. (e.g. if, defn etc). For included libraries, there will typically be a small set of macros that are core to understanding that library. Any macro will to modify, dare I say, complicate the syntax in the parens you are looking at so be on your toes.
Clojure is fantastic and easy to learn but those two points are not to be glossed over IMHO.
Before you start coding with Clojure, I highly recommend studying functional programming and LISB. In Clojure, everything is a prefix, and when you want to run and specific function, you will call it and then feed it with some arguments. for example, 1+2+3 will be (+ 1 2 3) in Clojure. In other words, every function you call will be at the start of a parenthesis, and all of its arguments will be follows the function name.
If you define a function, you may do as follow:
(defn newfunc [a1 a2]
(+ 100 a1 a2))
Which newfunc add 100 and a1 and a2. When you call it, you should do this:
(newfunc 1 2)
and the result will be 103.
in the first example, + is a function, so we call it at the beginning of the parenthesis.
Clojure is a beautiful world full of simplicity. Please learn it deeply.
So I'm new to Haskell and i'm trying to define a list which is a Max of 4 elements long.
so far I have type IntL = [Int,Int,Int,Int]
but I was thinking there must be a better/proper way of doing this.
Is there?
This is problematic in Haskell because phantom types encoding sizes need proper compiler support (otherwise it's pretty annoying to use), and type nats in GHC appeared somewhat recently.
That being said libraries exist, just to give you an idea.
Alternatively, just use a tuple.
it might look stupid and it certainly does not scale but what about
data Max4 a
= Empty
| One a
| Two a a
| Three a a a
| Four a a a a
with type IntL = Max4 Int? It's basic, you should be able to understand it and you can learn a lot by implementing operations on it.
Basic Haskell Types are not so powerful as to encode the maximum length of a list. In order to do that, you must rely on extensions such as GADTs and Phantom Types and yet it is not straightforward as well.
If you are really a newbie, I advice you to learn other basic concepts like Monads, IO and other idioms.
This site is a very good reading for an initial approach to Haskell:
http://learnyouahaskell.com
Is there a way to get ocaml to tell me if a function implements a recursion using tail recursion? I don't mean reading the code. I mean getting ocaml to tell me, say like this:
let x = tail_recursion f;;
You can compile your source code with '-annot'. It will produce an annotation file, that some editors can use.
In caml-mode (emacs) the command ist:
M-x caml-types-show-call
Along with the book "Simply Scheme" (Second Edition) i'm watching the "Computer Science 61A - Lectures" on youtube. On the lectures , the tutor uses Stk interpreter, but i'm using chicken scheme interpreter.
In the first lecture he uses the "first" procedure which if it's called like :
(first 'hello)
it returns "h".
On the book of "Simply Scheme" it has an example of how first can be implemented:
(define (first sent)
(car sent))
Which to my testing and understanding works if sent is a list .
I'm trying to understand if it's proper to say that "everything is a list" in scheme.
To be more specific where's the list in 'hello and if there is one, why it doesn't work in first procedure as it's written in the book?
Also if every implementation is written with "everything is a list" in mind why the same code does not work in all scheme implementations?
No, this is a common misconception because lists are so pervasive in Scheme programming (and often functional programming in general). Most Scheme implementations come with many data types like strings, symbols, vectors, maps/tables, records, sets, bytevectors, and so on.
This code snippet (first 'hello) is unlikely to work in most Schemes because it is not valid according to the standard. The expression 'hello denotes a symbol, which is an opaque value that can't be deconstructed as a list (the main thing you do with symbols is compare them with eq?). This is probably a quirk of Stk that is unfortunately taught by your book.
See The Scheme Programming Language for a more canonical description of the language. If you just want to learn programming, I recommend HtDP.
Not everything is a list in Scheme. I'm a bit surprised that the example you're showing actually works, in other Scheme interpreters it will fail, as first is usually an alias for car, and car is defined only for cons pairs. For example, in Racket:
(first 'hello)
> first: expected argument of type <non-empty list>; given 'hello
(car 'hello)
> car: expects argument of type <pair>; given 'hello
Scheme's basic data structure is the cons pair, with it it's possible to build arbitrarily linked data structures - in particular, singly-linked lists. There are other data structures supported, like vectors and hash tables. And of course there are primitive types - booleans, symbols, numbers, strings, chars, etc. So it's erroneous to state that "everything is a list" in Scheme.
With respect to Simply Scheme: the functions first and rest are not the standard ones from the Scheme standard, nor ones that come built-into DrRacket. The Simple Scheme API is designed as part of the Simply Scheme curriculum to make it easy to work uniformly on a variety of data. We can't make too many assumptions on how the underlying, low-level implementation works from just the experience of using the Simply Scheme teaching language! There's a runtime cost involved with making things that simple: it does not come for free.
Does R6RS or Chez Scheme v7.9.4 have a library function to check if a list contains duplicate elements?
Alternatively, do either have any built in functionality for sets (which dis-allow duplicate elements)? So far, I've only been able to find an example here.
The problem with that is that it doesn't appear to actually be part of the Chez Scheme library. Although I could write my own version of this, I'd much rather use a well known, tested, and maintained library function - especially given how basic an operation this is.
So a simple "use these built-in functions" or a "no built-in library implements this" will suffice. Thanks!
SRFI 1 on list processing has a delete-duplicates function (so you could use that and check the length afterward) and may well have other functions you might find useful.
Kyle,
Awhile back I needed to use a few SRFIs with Chez Scheme. A few that a converted for use with Chez Scheme (including SRFI-1) are at:
http://github.com/dharmatech/chez-srfi
After you add the path to 'chez-srfi' to your CHEZSCHEMELIBDIRS, you can import SRFI-1:
(import (srfi :1))
Ed