2018-11-10

The Thing

Danish: You look like you're going to spend your life having one epiphany after another, always thinking you've finally figured out what's holding you back, and how you can finally be productive and creative and turn your life around. But nothing will ever change. That cycle of mediocrity isn't due to some obstacle. It's who you are. The thing standing in the way of your dreams is; that the person having them is you.

Danish really has my number.

2018-07-19

Tclook

I seem to have created a basic tool to inspect TclOO objects and classes (etc).

https://github.com/hoodiecrow/Tclook

2018-04-10

Just like a woman


I mean, it's uncanny. Trying to distinguish that from an actual female author's writing would be like finding a needle in a haystack. If the needle is strongly magnetic. And has a blinking LED light and emits a small "beep" sound now and then. And there isn't very much hay.

More (Huffington Post)

2018-02-27

Feb 27

I was looking idly at http://yourbasic.org/golang/go-vs-java/, and my fingers started walking.

The most basic Tcl source for this I can think of is

proc Real c {lindex $c 0}
proc Imag c {lindex $c end}

proc Add {c d} {
    lmap c $c d $d {expr {$c + $d}}
}

proc String c {
    if {[lindex $c end] < 0} {
        format (%g%gi) {*}$c
    } else {
        format (%g+%gi) {*}$c
    }
}

set z {1 2}
String [Add $z $z]
But that's close to cheating. Let's at least make a class for it:
oo::class create Complex {
    variable re im
    constructor args {
        lassign $args re im
        if {$re != $re || $im != $im} {
            set msg {domain error: argument not in valid range}
            throw [list ARITH DOMAIN $msg] $msg
        }
    }
    method real {} {set re}
    method imag {} {set im}
    method add d {
        Complex new [expr {$re + [$d real]}] [expr {$im + [$d imag]}]
    }
    method string {} {
        if {$im < 0} {
            format (%g%gi) $re $im
        } else {
            format (%g+%gi) $re $im
        }
    }
}

set z [Complex new 1 2]
[$z add $z] string 
And that's it. Not a big deal. Unless you're working with Java, of course.

The biggest wart AFAICS is that Tcl doesn't allow implied conversions to string: everything has a string representation, but Tcl decides what it is. In the first code, this works in our favor, as the standard string representation (a string that is a list of two numbers) is identical to the model I used for complex numbers. Without calling String, the result of Add $z $z is 2 4, which is immediately useful both for printing and for further calculations.

In the second code, the string pseudo-representation is ::oo::Obj99 (or some other number), i.e. the name of the object command. The method string needs to be called explicitly to get a printable string that shows the data content.

Note that Tcl's expr command throws an exception with the message "domain error: argument not in valid range" instead of dumping a "NaN" message. You can still figure out that it was a NaN by looking at the message or by comparing the number to itself, as I'm doing here. I could have signalled the problem with the invocation "error NaN", but chose to emulate Tcl's handling instead.

2017-12-18

Ruby-style accessors in TclOO

A way to get Ruby-style accessors in TclOO. Inspired by code on the Tcl Wiki by “anonymous”, improved by Nathan Coulter. This code has been posted to the Wiki as well.

Accessors let you declare instance variables and getter and/or setter methods for them at the same time. The attr_reader and attr_accessor commands declare one or more variables and also methods for them with the same name, which return the current value of the variable. The attr_writer and attr_accessor commands declare one or more variables and also methods for them with the same name with an appended =, which take a value argument and set the variable to that value. So attr_accessor foo bar  declares the variables foo and bar , the getter methods foo and bar , and the setter methods foo= and bar=

namespace eval oo::define {
    proc attr {access args} {
        set class [lindex [info level -1] 1]
        ::oo::define $class variable {*}$args
        if {"reader" in $access} {
            foreach name $args {
                ::oo::define $class method $name {} \
                    [format {set %s} $name]
            }
        }
        if {"writer" in $access} {
            foreach name $args {
                ::oo::define $class method $name= v \
                    [format {set %s $v} $name]
            }
        }
    }
     
    interp alias {} attr_reader {} ::oo::define::attr reader
    interp alias {} attr_writer {} ::oo::define::attr writer
    interp alias {} attr_accessor {} ::oo::define::attr {reader writer}
}

2017-12-17

Defining a callback in Tcl

I have posted this text on the Tcl wiki as well.

Tcl uses the callback protocol for everything from higher-order functions to event-driven programming. As with so many other things Tcl, callbacks are fairly straightforward. Still, some explanation can be useful.

What is a callback?

A callback is "executable code that is passed as an argument to other code, which is expected to call back (execute) the argument at a given time" ([1], [2]).

In some cases, as when a -command option is passed to lsort, the receiving command (see below) immediately executes the code (blocking, or synchronous, callback). More commonly, a callback is specified in an after, bind, trace, I/O handler, or widget -command option, etc, and called when appropriate (event-oriented, deferred, or asynchronous, callback). A deferred callback must be able to execute even if the context where it was defined has since been destroyed.

2016-08-22

The structure of water

This is a nice quote:
In my experience, the best programming languages for just writing programs are those which have "the structure of water" as a zen enthusiast I once knew explained it. They can be deformed infinitely, without stress, to fit the shape their environment requires.
So, yes, I really and truly do prefer a multiparadigm language with a reasonably small, general working vocabulary, that doesn't make design choices for me. I like languages where object-oriented and functional programming (and imperative, and stream-oriented, and data-directed, etc) are all Things You Can Do rather than being The Only Way The Language Works.

Looking back on my own programming career, I find that the languages I have liked best (Lisp, C, Tcl) are very much like this description. The languages I have tried and given up on (Perl, Java, Python, C++) are more or less the opposite (Perl and C++ were designed to fit any user, but grew to be unwieldy and demanding).