Tuesday, 30 June 2020

(practical-python->racket approach)

Superficially, it seemed logical to start at the beginning. But upon reading the first few pages, it soon became clear to me that attempting to "translate" them requires a deeper knowledge of Racket than I have today. I thought it best to start with some easier material. So, I started with the introductory material about numbers, strings and lists that was easier to translate. I'll come back to the start later.

Each section of the course includes examples and exercises. My approach is to write a single Racket script which includes all the examples. (Is it even correct to refer to a short Racket program as a script?). I write a separate Racket program for each of the exercises. I'll write any notes I might have in this blog. I'll store the Racket programs in GitHub.

After a few false starts I managed to work out how to get the Racket that I've written to run in both Dr Racket and the Racket repl. I had written a few short Racket functions to reduce the amount of typing to complete the example scripts.

For example, instead of writing (displayln "Python: a = True") I can write (python "a = True"). It's basic text substitution. 

The function that I use to "expand" (racket value) is a little more sophisticated / complicated depending on you point of view.

(define-namespace-anchor anchor)
(define ns (namespace-anchor->namespace anchor))
(define (racket rkt)
  (cond
    [(list? rkt) (display "Racket: ")
                 (writeln rkt)
                 (eval rkt ns)]
    [(string? rkt) (displayln (string-append "Racket: " rkt))]
    [else          (displayln "Racket: Oops")])) 

The racket function will display its arguments and also evaluate the argument if it is a list. 

What took the time to figure this out was that you don't need to provide the namespace to the eval function when you run code in the repl unless you  specify #lang racket. It seems that Dr Racket insist on you specifying a language. So the code wouldn't run in Dr Racket.

I couldn't see a quick solution staring at me from the pages of the documentation. As I was really just performing text substitution, I thought I'd be better off writing a macro.

It took me number of attempts but I did eventually manage to get a macro to do pretty much the same thing. The issue that I came across was that I couldn't work out how to just expand the code with the macro and not evaluate it. So when I ran the script, all the macros were run before the rest of the code and the output was not in the order I wanted. (I guess I could have translated all my "expander" function to macros but I'll leave that for another time).

I went back to the docs and found that what I need to get my racket function working was to create and provide it a namespace. I first used make-base-namespace to create the namespace. I later found that I needed more modules than provided in racket/base to emulate the Python examples. Section 15.1 eval in The Racket Guide had a simple example of creating a namespace based on the "language" being used.

On to the first translation 1.3 Numbers.



Friday, 26 June 2020

(practical-python->racket introduction)

Recently, renowned Python expert David Beazley generously open-sourced his Practical Python Programming course. My Python skills are steadily improving through consistent use and watching talks and tutorials on YouTube. I've learnt a lot from David's talks and tutorials.

Sometimes I feel that my understanding of languages can be more theoretical than practical. I spent too much time learning and not enough time applying my knowledge. Practical Python Programming sounded exactly what I needed. I set out dutifully entering the examples into Python and doing the exercises. It was helpful. I even learnt that the Chicago Transit Authority #22 bus doesn't run at night.

What is Practical Programming though? Well to me, it's writing programs, short or long, to get things done quickly and efficiently. Effectively, it's turning a computer into a personal productivity tool. My current practical programming project helps me analyse companies. It is putting knowledge to use. 

I was mid-way through Chapter 1 of Practical Python Programming when a sudden thought broke my concentration. "This is just the type of material that would help me move forward with Racket. Hmmm, perhaps I should try coding the examples and exercises in Racket?"

So I tried out the introduction to Lists. I found I was able to "translate" the examples to Racket with some difficulty and quite a bit of "Doc Diving". During the process I expanded my knowledge of Racket and reinforced what I already knew. It seemed like a good idea to continue and get as far through the course as I could. I'll try to write about my experience in doing so in this blog as it helps me to remember what I've learnt.

I contacted David Beazley and he was happy for me to blog about my efforts to "translate" his Python to Racket. Though this is not in anyway his endorsement of the contents.

Another word of warning, this is very much a pseudo-mechanical translation. It's turning idiomatic Python into Racket. The code will certainly not be idiomatic Racket code. It could well turn out to be idiotic Racket code. Let's see.

You can read about my approach or go straight to the first section.




Monday, 22 June 2020

Learning Racket

I decided to try to learn Racket. Why?

It's not directly relevant to my current programming in JavaScript, Lua, Python and Rebol. Most of my programming work has been, is, and probably will be, run of the mill application software development. Since I started working as a programmer, languages such as Lisp, Forth and Prolog have always held an element of intrigue for me. They are different from the languages that I use.

Rebol is said to have both Lisp and Forth in its genes. But somehow, it doesn't hold the same level of intrigue. Perhaps its because the majority of people in the Rebol community were intent on using Rebol rather than discussing its design and implementation. The focus was far more on what you could do with Rebol than what you could do to Rebol. It could also be that, to quote a friend, "I wrote Rebol code the same way I wrote COBOL".  On the other hand, it could be that I have reached a reasonable level of fluency and the intrigue has faded during the process.

I didn't start out to learn Racket because I found it intriguing though. I had something else in mind. Functional programming is a hot topic these days (at least in the circles I'm connected with). It is the "only" answer to make use of the ever increasing number of cores in CPUs according to many of its proponents. Object oriented programming is frowned upon in the same circles these days. I use functions in my programs. I use objects in my programs. 

However, I feel that I have a superficial understanding of functional programming. I've taken a quick look at Erlang, studied books on functional programming in JavaScript and watched YouTube videos promoting functional programming in Python. I have an equally superficial understanding of object-oriented programming. I've half-heartedly studied Java in the past. I have learned a little Ruby and dipped in to the world of "proper" object-oriented programming. 

I believe that I would be a better programmer if I was more fluent in both functional programming and object-oriented programming metaphors. I decided to try to learn a functional style programming language and, after that, to properly try object-oriented programming. 

I've even identified two simple projects that I could use as learning vehicles. I know from experience, that I will only reach the level of fluency in a style of programming when I can use it productively by writing useful code in it.

It was easy for me to choose to use Ruby as a medium for object-oriented programming. The choice was not so easy when it came to functional programming.

I was encouraged to learn Elixir. It seems to have taken over some of people's previous enthusiasm for Ruby. People mentioned "SICP" in glowing terms insinuating that it is the seminal functional programming text. You can follow SICP using Racket. In the past, I had heard favourably of Racket. I took a look. It is very professional presented with a lot of documentation. It is easy to install and get started. 

I decided to work through "How To Design Programs" or HTDP as it appears to be snappily known. I chose the word work carefully. I completed around 40 percent of HTDP and did about 90 percent of the 240 exercises I have so far encountred  I probably spent an hour a day studying HTDP. Sometimes it felt a little like "Wax on, wax off" as the exercises felt a little repetitious to me.

It was taking too long to hold my attention, so I switched to The Racket Guide. I made faster progress but also soon realised that I'll need to complete reading most of the guide before I can start writing Racket programs.

At the moment, I still feel that I have a way to go before I can start on even a small project in Racket to start building some actual fluency. I'm not sure that I have the stamina to finish The Racket Guide as an academic exercise.

Thankfully, I have stumbled across another approach which has boosted my enthusiasm which you can read about at (practical-python->racket introduction).



Saturday, 28 April 2018

Swift divideWithOverflow doesn't - Update 2

Quite a long time ago I came across an unusual circumstance that crashed Swift int32divideWithOverflowI reported the bug to see the details.

Since then ...divideWithOverflow has morphed into divideReportingOverflow and it fixes the issue in some cases but not quite all yet.

Sunday, 25 February 2018

Installing Watir and Python Selenium on macOS

I have been using Watir on and off for quite a long time, seeing it develop from Watir through Watir-Webdriver and back to Watir. I needed to install its latest incarnation and hit a few problems. The problems were caused more by my impatience in not reading through the notes on the Watir website than anything else.

At the same time, I decided to install the Python Selenium package to try it out. It also didn't work out of the box. Once again, the problem was that I hadn't been sufficiently thorough in reading the instructions.

The main problem with both was the need to install the Firefox and Chrome web drivers and to configure Safari's. After a little trial and error and reading through  the documents, the simplest way came to the surface.

I installed the Firefox and Chrome web drivers using Homebrew: 
    brew install geckodriver
    brew install chromedriver

My Safari installation was already configured to show the Develop menu and I have Allow Remote Automation menu item selected. From the Watir Safari Driver page, I found that I need to run safaridriver once from the command line to give it the proper authorities. I needed to run it from an administrator account:
     sudo /usr/bin/safaridriver

After that both Watir and Python Selenium both will happily load Safari, Firefox and Chrome when run from a macOS user account.

Thursday, 19 October 2017

Overcoming My Pythonaphobia

I've taken a good first step to overcoming my Pythonaphobia. I was given the chance to review the third edition of Practical Programming by Paul Gries, Jennifer Campbell and Jason Montojo published by The Pragmatic Bookshelf.

It is an excellent introductory book aimed primarily at people studying in a university setting. It teaches both Python and solid programming techniques. I feel that it would be an excellent second or third book for somebody whose introduction to programming has been via the Raspberry Pi.

From reading the book, I was able to see some strengths of Python compared with languages with which I am more comfortable. For instance, I really liked doctest and, thanks to Practical Programming, Python's straightforward object model.

I continue to find Python's syntax too fussy. It's indentation, line continuation marks, etc. make it feel somewhat pre-historic: the RPG of the modern age.

Still, thanks to Practical Programming, the seemingly ever growing popularity of Python and it being at the heart of Raspberry Pi, I am encouraged to look a little deeper.

Tuesday, 15 August 2017

Busted or LuaUnit? Answered

I didn't have the time to complete a thorough evaluation of Busted and LuaUnit but have come to the conclusion that I will use Busted. Both Busted and LuaUnit work well and, given Lua's dynamic nature, I found it easy to write tests with them.

I came to my decision after going back to the Stockfetch tests after a gap of two or three months. It was much easier to work out what was being tested from the Busted tests than it was from the LuaUnit ones. It was because of the names that I had given the tests not any failing on LuaUnit's part.

So my choice was not made on a technical basis but because Busted encourages me to write more understandable tests.

I also found, in some cases, Busted's spies, stubs and mocks made for shorter test code than using Lua's flexibility with LuaUnit. On the other hand, LuaUnit tests seem to run much quicker than Busted's. Around ten times faster in my case.