STARTING A NEW JOURNEY... Trying CLOJURE 1.10.1
Ernesto Luís Suvá
Project Manager - Scrum Master - Scrum Product Owner (TOEIC PMP PSM I SPS PSPO I PSD I) EU citizen (Spanish with NIF) & ESTA approved.
This is the continuation of the following article:
And the following post:
Do not forget to consider reading them.
First... HAVE A HAPPY 2025 NEW YEAR!!! AND BEST WISHES TO EVERYBODY!!!
Journeys are journeys… You only know where you start and the direction of your first step to where you want to go… and sometimes you stop your walk to review what you have done. This is one of these cases.
Let us start thanking Karthikeyan A K for his Clojure book. It was my CLOJURE kick-off.
It is a completely "hands on" language book. I think that it is not the author’s purpose to cover functional programming theory. Anyway, I felt like I was visiting a craftsman's workshop. The owner was showing me the tools and materials he worked with. And then he gave me the key to the workshop so I could go and try out his tools and materials whenever I wanted.
So, one day, I decided to open the door, and start "my game"!!!
I thought that, with my knowledge, the “learning curve” were not going to be so high (or deep) … I was totally and completely wrong!!!
Let me introduce some of my experiences:
When I was at college I first coded in Assembler, COBOL, FORTRAN, ALGOL, and suddenly, someday, the “formal languages” faced me… I was astonished. In particular, the way the functional programming languages solved problems completely changed my mind. Coding in LISP and in PROLOG were completely different (I got a 10 (A+) at the university course and I was accepted as teaching assistant "ad honorem" at the university during the following year).
I subsequently specialized in data warehouse modeling, relational and non-relational databases, with the goal of building analytical systems to help C-level clients make better business decisions.
Coming back to functional programming (and its application in AI), let me now introduce you to some of the books I read while coding (some in more detail than others):
Back to my LISP coding, I used an ANSI Common LISP implementation by Bruno Haible and Michael Stoll, known as CLISP, which was no longer updated. Its latest version is 2.49, dated July 7, 2010. I not only coded in Common LISP I also coded in CLOS (Common LISP Object System – the Object Oriented “extension” for CLISP): CLISP - an ANSI Common Lisp Implementation
So, let us return to CLOJURE… For me, it has no importance if CLOJURE is a LISP-1 representative and ANSI Common LISP is a LISP-2 representative. What was important is that jumping from the second to the first one, was not an easy experience.
WARNING!!! WARNING!!! WARNING!!!
Everything that I am going to write below is coded and commented on by me, during this last half year, based on the book written by Karthikeyan A K, the Clojure Cheat Sheet (Clojure 1.8 - 1.11, Sheet V55) by Steve Tayon and Andy Fingerhut and some (to not say a lot) Internet surfing.
Everything was tested using UBUNTU 20.04.6 LTS + OpenJDK 64-Bit Server VM 21.0.5+11 + CLOJURE 1.10.1 + LEININGEN 2.9.1 + VSCODIUM 1.96.1 release 24353 + CALVA 2.0.482
The problem is that running a REPL outside of a LEININGEN project (by running lein repl in an UBUNTU terminal window) causes LEININGEN to only use CLOJURE version 1.10.1 (dated in Jun 2019).
It is possible to change the CLOJURE version by running LEININGEN inside a project (by modifying the project.clj file). Due to not creating any project yet (something I will do in the future), everything is coded, run, and tested under the 1.10.1 version.
I also modified the profile file in my UBUNTU installation (located in the /etc folder) including at the bottom, the following line, for letting JAVA use some of the swap partition I had created (remember that I am using an old notebook for this journey):
export JAVAOPTIONS=”-Xms4g -Xmx16g”
As I wrote before, the craftsman gave me the key to his workshop, and I have been going there for the last months…
I started with a simple file, coding different examples I read and, without realizing how high (or deep) I was traveling on my learning curve roller coaster, suddenly, I became aware that I had written thousands upon thousands of lines of code with their corresponding evaluation results (including some comments of my own).
The result… six different A3 .pdf file sizes in 8 font size, that you can freely use throughout your journey (opening them and using select, copy and paste). They include more than 25.000 lines of code (some in blank). I hope they complement and expand on many of the answers to questions that arise when programming with CLOJURE (with a little more time, merging, indexing, and choosing a good cover for the six files, I could have made a workbook including the evaluation results and my comments).
Nowadays, I think what happened to me was something like with the Yoko Taro's Japanese video game Nier Automata. By the way… Do you know it? Have you played it? It was the "What if?" way of thinking that made me try everything I could imaging using the CLOJURE language.
Some general comments:
CLOJURE is really IMMUTABLE. The only way I remember I found (until now) to break it, is for names defined by def or defn, like in the following two cases, evaluated from top to bottom (yes… I know… It is really not fair??):
(def num-list (list 1 2 3))
(println num list) the evaluation result is (1 2 3)
(def num-list (list 2 3 4))
(println num list) the evaluation result is (2 3 4)
领英推荐
(defn arith-op [x y] (+ x y))
(arith-op 2 3) the evaluation result is 5
(defn arith-op [x y] (- x y))
(arith-op 2 3) the evaluation result is -1
There are JAVA types for data (and data structures) and there are CLOJURE types for data (and data structures).
It is common that the result of evaluating a function applied to a data (or a data structure) with a data type (or data structure type) changes its type.
There are different syntaxes for creating the same data type (or data structure type), The same function applied to the same type of data (or data structure) may work with one syntax and not with another syntax of the same data (or data structure).
Not every function is applicable to any data type (or data structure type). And when it is, the evaluation result, sometimes, is different, according to the type of data (or data structure applied) (e.g. it could be () or it could be nil for the same function).
Both () and nil can be data, the result of an evaluation, a data type, or a data structure type.
So far, I have found that the result of an evaluation is able to be one of the following five: the expected one, an unexpected one, an inconsistent one, an execution error, or a syntax error.
And there are more…
In other words, my advice: test, test, test, and test, every line you code in CLOJURE, for every value you imagine that line could be used to!!!
And now, the six .pdf files (searching my feature section from my profile - sorry... I could not find a way to include them in the article, maybe it is not possible - you will be able to find them and, after opening any of the .pdf files, you will find that, at the left there are the CLOJURE expressions, and at the right the evaluation results with some comments):
lein_repl_clojure_1.10.1_part_01_ver_01.clj.pdf
The first one includes two ways to print (println, print), the type function, different types of numbers (long, double, bigint, N), some range testing of numeric types, increment and decrement functions (inc, dec), arithmetic ( +, -, *, /), dividing with zero numbers, arithmetic with positive numbers, arithmetic with positive and negative numbers, the ratio data type, the quot and rem functions, some of the JAVA math library, the “Is it” functions (number?, integer?, double?, ratio?, pos?, zero?, neg?, even?, odd?, string?), the string type (str), counting characters (count), the string? function, some of the CLOJURE inbuilt string library, global variables (def), and local variables (let).
lein_repl_clojure_1.10.1_part_02_ver_01.clj.pdf
The second one includes the seven data structures I tested, with all their different syntaxes (lists, vectors, hash sets, hash sets using keywords, hash maps, array maps, and array maps using keywords) applying to each one the same set of functions (def, conj, cons, assoc, disj, keys, vals, count, first, last, rest, nth, get, contains?, string?, list?, vector?, set?, map?, coll?) and also, getting elements without function, and testing repeated elements on the seven data structures.
lein_repl_clojure_1.10.1_part_03_ver_01.clj.pdf
The third one includes logical and comparison functions (=, >, >=, <, <=, and, or, not, nil?, empty?, symbol?), conditional and branching local functions (if, do, when, cond, :else, case), global immutability binding of data structures (def), local loop functions (for, doseq, loop, when), global functions with and without arguments (defn), the last clause return of a function, tail recursion with or without using the recur function, the identity function, functions with multimethods or without them with recursion or without it, the pre and post condition argument checking and the anonymous functions, how to document functions, different syntaxes for anonymous functions, the defn syntax function, and returning functions.
lein_repl_clojure_1.10.1_part_04_ver_01.clj.pdf
The fourth one includes (in Part I) specifications using the clojure.spec.alpha library: the s/valid? function with the “Is it” functions nil?, empty?, number?, integer?, int?, double?, ratio?, zero?, pos?, neg?, string?, symbol?, keyword?, list?, vector?, set?, map? applied to nil, numbers, strings, symbols, keywords, lists, vectors, hash sets, hash sets using keywords, hash maps, array maps, array maps using keywords, map entries, keys, values, constructs, and lazy sequences; and it also includes (in Part II) specifications using the clojure.spec.alpha library: the s/valid? function with s/and and s/or, specifying in collections (s/coll-of), inspecting collections of vectors using array maps with keywords (s/cat), inspecting collections of array maps using keywords (s/keys), checking collections of array maps using keywords with keywords (s/def, s/keys), explaining and conforming to specifications (s/explain, s/conform), and explaining specifications on checking pre and post conditional argument.
lein_repl_clojure_1.10.1_part_05_ver_01.clj.pdf
The fifth one includes sequences and converting them into different data types (or data structure types) (seq, sequence), counting sequences (count), and partitioning sequences (partition).
lein_repl_clojure_1.10.1_part_06_ver_01.clj.pdf
The sixth one includes lazy sequence functions (take, repeat, cycle, iterate), more functions (map, range, filter, reduce, apply), destructuring lists, vectors, hash maps, and array maps, threading macros (->, ->>, as->, cond->, cond->>), regular expressions (re-matches, re-find, re-seq), regular expressions with string functions (str/replace, str/split) using the clojure.string library, splitting large programs and loading them (defn, def, load-file), records and protocols (defrecord, def, ->, get, map->, defprotocol, describe, let, def, extend-protocol), name spaces (ns, user/), testing (deftest, is, testing), and macros (defmacro, macroexpand).
Well, that is all for now… To be continue…
Hmm… I think it would be a promising idea to learn and build a LEININGEN project to use the last version from CLOJURE, trying to use it to solve some little square type puzzles – before continuing learning from the following two books:
Concluding this article differently, as usual, here is another draw example (an anime / manga character sketch that I guess you know):
Making JavaScript devs life suck less.
2 周Wow! Thanks for mentioning my book!
Commercial Responsible | Business Development | KAM | Business Management | Sales Strategist en SKF Group
1 个月Felicitaciones por el libro!
Abogada/ Agropecuaria
1 个月??????????????