jueves, 29 de diciembre de 2011

Invincible Perl



Have you seen the talk about DoSsing websites just using crafted data on forms (POST)? It's the trending topic of this week.

Well, here you have a couple of links related to this talk and some extra info.

The interesting thing that surprised me (or not so) on that article/talk is that the only language they tested that's not vulnerable to this attack is.... guess what? Perl. Here's the extract of the article:

Julian and Alexander did a great job with checking many programming languages used for web applications for their hash table implementation and hash functions. For all of them they checked, they managed to find a lot of keys mapping to the same output, except for Perl. Perl uses a randomized hash function, i.e. the hash doesn’t only depend on the key, but also on an additional value, that is chosen at startup of the application at random. All other languages also store the query parameters send in an HTTP GET or POST request in an hash table, so that a request with many query parameters all mapping to the same hash value will slowly fill such a hash table, before the first line of code written by the application programmer will be executed. Filling this hash table will usually take several minutes on a decent CPU, so that even a fast web server can be kept busy using a slow connection.

And here you have HN comments

+1 for Perl!
Between offtopic and related here's another nice talk from 28C3 that's having place these days in Berlin.

martes, 27 de diciembre de 2011

Git, the stupid content tracker, or not so


After roughly a year of using git daily, one has already crossed the "WTF!?" side and now is in the "It's obvious" land.

After getting help from all coworkers I had last year, lots (I mean *LOTS*) of reading, and many moments of "Am I the only one in the world that doesn't get this?", all regular processes go without thinking now, and I know pretty much what is happening under the hood.

Some things are still a bit raw on the edges, but mostly because they aren't used so often (submodules, bisect...), but I digress...

Thing is that using and knowing git gives you extra power, not directly related to versioning code. As Linus said: "git is the stupid content tracker", it manages blobs of bytes.

  • git grep: Probably faster than grep -ri, and more focused to what you surely want to search. I've already integrated it with emacs, and try to use it more and more, instead of rgrep, or ack.
  • git ls: great for the kind of find-file-in-project functionality.
  • git log -Sfoo : Search throughout the history
  • git log -p : modifications in context
  • git annex: manage whatever content
  • using git to deploy: There's capistrano, and puppet, and chef, and... but git can handle it if configured properly. Probably this can end in a mess if you need to trigger many things when deploying. You know, there are hooks and everything, and you cand build your poor-man-capistrano. It's just your choice. But definately for mostly static sites, it's a nice thing to keep in mind.
  • Not really a git feature, but thanks to magit, or fugitive, you can have a pretty painless integration with your workflow, so it's a win. And you feel safer

Have more tricks? Comment!

Ok, after a bit more than a month, there's a post precisely on that. Nothing new in the article, but there are nice insights in YC comments

domingo, 11 de diciembre de 2011

martes, 22 de noviembre de 2011

tramp + shell = win

Did you ever notice that tramp is a great piece of elisp? I hope so.

The nice thing I discovered today is that it's highly tighted to the whole system, and if you just m-x shell when you're in a file opened through tramp, it'll open a shell in the remote system.

Super nice.

domingo, 20 de noviembre de 2011

Creating a simple common lisp application

After giving a further look at common lisp (a bit of PAIP, and PCL), I've found a project that can be a nice 1st app for me.

To develop a common lisp app, first you need to set up the environment and choose the toolchain. These have been my decisions. Tips are pretty appreciated.

Requirements

The requirements are the bare minimum for common lisp. I use SBCL myself, and don't know much of the differences between implementations. sbcl works just fine.

Editor

I use emacs 24, with slime, paredit and autocomplete. Use whatever you feel like but notepad. Obviously, emacs is recommended :)

Libs

Use quickload to find and load libraries. It's surprisingly easy and straightforward to use.

Project

quickproject to initialize the project is a nice way to avoid writting bolierplate, and to make sure your project will be loadable through ,load-system.

Tests

I tried a couple of testing packages for common lisp, and decided to go with lisp-unit due to its simplicity and availability in ql repos.

Code repository

The code is being hosted in a private git repo in bitbucket. They give you unlimited public/private (*yes*, private) repos, using git/hg, with issue tracking and all, for free. It seems a nice nice alternative to github. great to host projects in early stage where you don't feel like sharing the code to the world.

That's it for now. There's no public code for the moment... There's nothing to see here :)

sábado, 12 de noviembre de 2011

change emacs url-browser

When you click an url in emacs, it'll open a browser with that url. That's fine.

Problems arise when you have multiple browsers and they fight to be your preferred one. In a coworker's box, it tries to open konqueror (WTF?!).

One way to fix the issue is changing browse-url-browser-function.


(setq browse-url-browser-function 'browse-url-generic
browse-url-generic-program "chromium-browser")


Not only that, but the nice thing would be that emacs reused a browser if you have one opened (firefox or chrome) and opened a new one (chrome) otherwise.

I've been messing a bit with proced.el to find out how to list external processes programmatically, but had no luck. If I find out how, I 'll modify this post with new info.

If you have related info, please, comment :)

Thanks to Davazp that pointed me to list-system-processes function, I just wrote the code to use an already opened browser to open a given url.

(defun is-proc-opened (procname)
(let ((procs (list-system-processes)))
(remove-if-not (lambda (proc)
(search procname
(name-of-proccess proc)))
procs)))
(defun name-of-process (proc)
(cdr (car (process-attributes proc))))
(defun browse-url-open-browser (url &rest new-window)
(setq browse-url-generic-program (open-browser))
(apply 'browse-url-generic url new-window))
(defun open-browser ()
"define the priorities of browsers"
(if (is-proc-opened "chromium")
"chromium-browser"
(if (is-proc-opened "firefox")
"firefox"
"chromium-browser")))
(setq browse-url-browser-function 'browse-url-open-browser)
view raw open-browser.el hosted with ❤ by GitHub


A good quickreference to look for function signature differences between elisp, scheme and cl is here. It helps quite a lot

domingo, 6 de noviembre de 2011

Metacircular game of life.W00t!

Here are a couple of links on game of life info.

First of all, a game of Life implemented in one line of APL, explained, so you can even try to understand it. Then, a couple of articles on cellular automatas, explaining game of life basics and not-so-basics.



And the really amazing stuff: Metacircular GoL

domingo, 23 de octubre de 2011

Introduction to (modern) Perl (course)



Barcelona Perl Mongers are organizing a 8 hours course on Perl intended for programmers that have no or little experience in Perl. It's not an introductory course to programming.

The course will be on November 5th, at UPC (Barcelona). 25 Euros for the course, and an exclusive T-Shirt.

I'll be there, maybe just listening, or helping answering questions.



viernes, 14 de octubre de 2011

I still think Perl

The other day, a friend asked how to split a string by commas, but only if they aren't inside a tag, say enclosed by '<' and '>'. I tried python, but somehow regexes are so hardwired in my head, that I can't work with languages that do not have regexen so hardwired in their heart.

Here it is. Tiny, but gets the job done. And that's what perl is for. a regex with lookbehind stuffed into split. No problem sir!

perl -e '
$_="<item1>, <item2>, <item3>, <item4 , item5 ,foo>";
print split(/(?<=>)\s*,\s*/), "\n";
'

lunes, 10 de octubre de 2011

steve, the web, and innovation.



It's been less than a week a genius left us yada yada yada.....

Since last October 5, I've been thinking a lot about Alan Kay and I was waiting to see some references from sites talking about MrJobs to Mr.Kay.

Well, today I've seen it, and this post will be just a kudos to people knowing the real story, that Steve had great qualities, and was visionary in a very bright way, but he didn't invent the future. You know...

But the internetz has gone crazy on this, so I wanted to point out a couple of curiosities I've seen since then.

- First, a HN screenshot I did the 'day of the facts'.
- Then a post talking about Alan Kay, linked from a 'outstanding articles' widget, pairing with Steve.
- Now a great and long post about great things that happened at XEROX PARC, and things Jobs saw there, and how he implemented then in Apple. He didn't invent the mouse, but simplified it (in fact, Xerox didn't invent it either), he didn't invent GUI, but adopted it, and he didn't invent the iPad, but 'implemented' it, in the exact moment there was market for it.

Cya!



Btw, if you wanna know more about Kay and friends, here is another post on this blog with amazing videos, or just check the internetz, or just download pharo/squeak.

Ready, set, Dart!



Today there's been the first official press info and release of Dart language. A class-based language developed by google.

Features: OOP, class-based, optionally typed, and thought for the web. It seems it'll have a client side debugger. (Hello amber! :p )

Lars Bak has been strongly involved in Dart, and given his smalltalk past life, it's sensible to say that we'll see some familiar things in there.

Today is the first day of AI classes in the standford open course. For the moment, browsing the notes of the first class...



See the flash bar in the top? :)

domingo, 9 de octubre de 2011

Emacs 24 is frozen

Emacs 24 entered the feature freeze state a couple of weeks ago, so it's the moment to install it and start fiddling with its new features (I want to try the editable occur buffer, and some asynchronous goodies for gnus).

There have been a couple of posts in planet emacsen that explain how easy is to install it in debian or ubuntu (natty).

The thing is that I use an older ubuntu version and I had to compile it myself. Not very problematic, but here's the couple of libs that I had to install before being able to compile it. Obviously, you'll need the usual binutils and dev tools. also you'll need these packages.

apt-get install autoconf texinfo libxpm-dev libgif-dev libgtk2.0-dev xserver-xorg-dev xorg-dev libfontconfig-dev libfreetype-dev libxft-dev # probably, not everything is needed, but once you warm up, apt-get is too easy.

Then, just get the code from the repo, and configure install in proper directory:

git clone https://github.com/emacsmirror/emacs.git 
cd emacs
./autogen.sh
./configure --prefix=~/emacs-24
make install


Now you have your emacs in ~/emacs-24/bin/emacs, and hopefully, everything will work from the beginning. I had to disable a couple of lines in my .emacs file, but just minor things.

Now it's time to try emacs-starter-kit 2.

martes, 4 de octubre de 2011

Is it really that bad? Seems so

In the last couple of days there's been quite a lot of ranting about overly complex software we have to manage daily. It applies to software we use (super-complex UI and over-featured apps) and software we develop Does it really make sense to deal with so many layers of added complexity to deal with mostly simple (conceptually) problems.

In those texts, they talk about 'old friends' like boost, SDL, Xcode, Objective-C, never-ending-toolchains, and supercomplex interfaces to third party software (APIs, security layers, etc.).

In my opinion, and without having spent as many years as those guys (or commenters at HN) on computers, it's true that the starting barrier to any new environment seems overly complex for the functionality we get. Most of the times, external tools solve deficiences of languages. Being a tool geek myself (probably, I have spent more hours than you trying and configuring window managers and editors), I have the feeling that entering most of new environments is more complex than it should be.

Want to do a rails app? no problem, you just have to handle a few technologies/tools:
ruby, rails, cucumber, rspec, rack, passenger, bundler, rvm, gems, html, js, ajax, css. Then, keeping compatibility with Chrome, firefox, safari, opera and, God forbid, IE.

Not bad, eh?

Well, if you want to write the views in a more confortable way, you can use haml, sass, compass, coffescript, that will compile to their ancestors, and will make you a happier person.

You see? (I hope you get the sarcasm)

Every now and then I think about Dan Ingalls quote:

"An operating system is a collection of things that don't fit into a language. There shouldn't be one"


And drool when thinking about smalltalk.

martes, 27 de septiembre de 2011

Bihain de uindou

Demasiadas veces mirando por su ventana y quedándome en blanco. veo
que algo se mueve ahé dentro, y veo la ventana mirándome, y la veo a
ella mirandome a través de la ventana. A veces, incluso me veo a mi a
través de ella a través de la ventana.

Y aún no sé qué decir (me y le). Y te.

Señalar con el dedo y ver el nombre en verde.
Clicar. Cerrar. Clicar. Cerrar. Y repetir.

sábado, 17 de septiembre de 2011

Amber language (former jtalk), digging deeper


Lots of changes have happened in jtalk world since last week.
  • Jtalk is now Amber. The project has changed its name when the 0.9 release happened. That means that the repo is now different, and the website too.
  • JQuery bindings have been removed from the system. Now we can access javascript objects directly, and use asJQuery in the same way, so there's no drawback, only the way to deal with jquery is more smalltalkish. Counter new appendToJQuery: 'body' asJQuery works perfectly, so no problem.
Creating functions
If you want to know a bit more on amber, you have to keep in mind that it's a smalltalk, so you can explore everything in your IDE. Let's try to find out a bit more on how the compilation from smalltalk to js works. This will allow us to debug our in a lower level than usual, and find glitches in our codes, or detect where our closure is missing the variables (when interfacing with js, sometimes it's useful to see the whole js code, and make conclusions on js).

Let's create a new class Foo with a method that gets a block (callback) and executes it. Now, to find out how it's compiled, we'll make amber print the compiled source of the method:
(Foo methodDictionary at: 'get:') fn compiledSource "print it".

If we print it, the result will be the js source of the method

// function returning self
//
// Foo>>get:aBlock
// |tmp|
// tmp :=3.
// aBlock value: tmp.
function (cb){
var self=this;
var tmp=nil;
tmp=(3);
smalltalk.send(cb, "_value_", [tmp]);
return self;
}
// function returning the result of the callback
// Foo>>get:aBlock
// |tmp|
// tmp :=3.
// ^aBlock value: tmp.
function (cb){
var self=this;
var tmp=nil;
tmp=(3);
return smalltalk.send(cb, "_value_", [tmp]);
return self;
}


You can try variations like returning explicit values, try to pass instVars to the closure, and see what is the translation to js. This helps sometimes to find out your way.

Can I inspect?
Inspector is there, but for the moment, it's in very early stage.

Debugger
Debugger is also there, also in early development. You can see the stacktrace, and inspect the methods, but not changing values and so.

NodeJS

We can use amber for the server side, running the generated javascript on node.js. Due to the hability of Amber to interoperate with plain js, we can use a shitload of libraries from amber. Here follow a couple of examples of amber on node.js

Server
Nicolas Petton wrote a fileserver meant to be used in the node.js side. This allows us to commit changes to our files transparently without the need of webdav,python(see last post), or any external server. It's Amber all way down.

The usage is fairly easy. Just cd to the root amber directory and run ./bin/server, that will run ./server/FileServer* things.

IRCBot
Trying the node.js part of amber, we can try to build a small program, and as no programming language is complete unless it has a IRC bot in it, let's solve this issue:) Btw, I hacked a couple of emacs functions to deal with st files a bit better.
Object subclass: #STalkerObject
instanceVariableNames: ''
category: 'IRCBot'!
!STalkerObject methodsFor: 'logging'!
log: aString
console log: 'RECV - ', aString.
!
info: aString
console log: 'INFO - ', aString.
!
error: aString
console log: 'ERRR - ', aString.
!
warning: aString
console log: 'WARN - ', aString.
! !
STalkerObject subclass: #STalkerPlugin
instanceVariableNames: 'socket'
category: 'IRCBot'!
!STalkerPlugin methodsFor: 'initializing'!
socket
^socket
!
socket: aSocket
socket := aSocket.
!
raw: aString
socket write: aString, String crlf.
!
say: aString to: aChannel
self raw: 'PRIVMSG ', aChannel, ' :', aString.
!
handle: data
^(self pattern: data) ifTrue: [self doYourStuff: data]
! !
STalkerPlugin subclass: #PingPlugin
instanceVariableNames: ''
category: 'IRCBot'!
!PingPlugin methodsFor: 'initializing'!
pattern: aLine
^ (RegularExpression fromString: '^PING :(.+)') test: aLine.
!
doYourStuff: data
self info: 'Answering ping to: ', data.
self raw: (data replaceRegexp: 'PING' with: 'PONG').
! !
STalkerPlugin subclass: #FreenodeLoginPlugin
instanceVariableNames: ''
category: 'IRCBot'!
!FreenodeLoginPlugin methodsFor: 'initializing'!
nickname
^ 'StalkerBot', 1000 atRandom.
!
password
^ nil
!
realName
^ 'JTalk/NodeJS Bot'.
!
pattern: aLine
^ (RegularExpression fromString: '^.*No Ident response.*') test: aLine
!
doYourStuff: data
self info: 'Loging in as ', self nickname.
self raw: 'NICK ', self nickname.
self raw: 'USER ', self nickname, ' 8 * : ', self realName .
! !
STalkerPlugin subclass: #AutojoinPlugin
instanceVariableNames: 'channels'
category: 'IRCBot'!
!AutojoinPlugin methodsFor: 'initializing'!
initialize
super initialize.
channels := Array new.
channels add: '#jtalk-bots'.
!
addChannel: aString
channels add: aString.
!
pattern: aLine
":StalkerBot MODE StalkerBot :+i"
^ (RegularExpression fromString: '^.+MODE.+\+i.*') test: aLine
!
doYourStuff: data
self info: 'Autojoining channels.'.
channels do: [ :channelName |
self raw: 'JOIN ', channelName.
self info: 'Joining ', channelName. ].
! !
STalkerObject subclass: #IRCBot
instanceVariableNames: 'plugins'
category: 'IRCBot'!
!IRCBot methodsFor: 'initializing'!
initialize
super initialize.
self initializeWithPlugins: (Array with: PingPlugin with: AutojoinPlugin with: FreenodeLoginPlugin).
!
initializeWithPlugins: pluginsToAdd
self addPlugins: (Array withAll: pluginsToAdd).
!
addPlugins: anArray
plugins := anArray collect: [:aPlugin| self spawnPlugin: aPlugin].
!
spawnPlugin: aPlugin
self info: 'Plugin loaded: ', aPlugin name.
^(aPlugin new socket: socket).
!
start
console log: socket.
socket on: 'connect' callback: [ self info: 'Hem connectat'] .
socket on:'data' callback:[ :data | data linesDo: [:line |
self log: line.
line = '' ifFalse:[ self handle: line]]].
socket setEncoding: 'ascii'.
socket setNoDelay.
socket connect: 6667 host: 'irc.freenode.org'.
!
handle: data
plugins do:[:plugin | plugin handle: data ]
! !
!IRCBot class methodsFor: 'initialization'!
initialize
socket := < new require('net').Socket()>.
!
main
self new start
! !
view raw IRCBot.st hosted with ❤ by GitHub

domingo, 11 de septiembre de 2011

can your editor^W OS do this?



Here is an emacs feature that it's hard to believe until you see it working.

m-x butterfly


Unbelievable, no?

Well, let's link this amazing functionality to the gesturing strokes-mode.

m-x strokes-mode
m-x strokes-global-set-stroke


Then, click in the buffer that appeared, and draw(drag) a circle with your mouse. when you end, press the right button.

now emacs will ask you for a command. Now it's the butterfly turn. write 'butterfly'.

Ok, now you have configured and amazing mouse gesture that will flip bits on your hard drive only by reproducing the figure (circle) you just did before.

in any buffer, press shift and draw a circle dragging the second mouse button (mouse wheel probably).

ENJOY!

PS: I've changed the shortcut from the second button to first, and now I can use my tablet to manage emacs. And here's another great thing of the ubiquity of emacs: You can use it to manage things related to irc,jabber,mail,text editing, playlist managing and even pdf reading. neat.

viernes, 9 de septiembre de 2011

emacs and smalltalk, a bit closer

Today I've been hacking around with jtalk. Implementing something for the node.js backend means that probably you'll be using your editor of choice.

I've downloaded paolo bonzini's smalltalk-mode.el

I've hacked some shortcuts to navigate through classes using emacs narrowing feature.

Here's the hack:

(require 'smalltalk-mode)
(setq auto-mode-alist
(append '(("\\.st\\'" . smalltalk-mode))
auto-mode-alist))
(defun smalltalk-narrow-to-object ()
;;(interactive)
(let* ((from (save-excursion (or (search-backward "! !" (point-min) t) (point-min))))
(to (save-excursion (or (progn (search-forward "! !" (point-max) t)) (point-max)))))
(narrow-to-region from to)))
(defun go-to-next-class ()
(interactive)
(widen)
(let ((to (save-excursion (or (search-forward "! !" (point-max) t) (point-max)))))
(when (not (= to (point-max)))
(search-forward "! !" (point-max) t)
(re-search-forward "^\\w" (point-max) t))
(smalltalk-narrow-to-object)))
(defun go-to-prev-class ()
(interactive)
(widen)
(let ((to (save-excursion (or (search-backward "! !" (point-min) t) (point-min)))))
(when (not (= to (point-min)))
(search-backward "! !" (point-min) t)
(re-search-backward "\\w" (point-min) t))
(smalltalk-narrow-to-object)))
(add-hook 'smalltalk-mode-hook
(lambda ()
(local-set-key (kbd "C-c n") 'go-to-next-class)
(local-set-key (kbd "C-c p") 'go-to-prev-class)
(local-set-key (kbd "C-c a") 'widen)))
view raw jtalk.el hosted with ❤ by GitHub

jueves, 8 de septiembre de 2011

HN Frenzy

HackerNews is not in its greatest moments lately, but today, lots of diferent great articles/links appeared. It's a bit overflow of info in just one moment, you open a handful of links and you face.



Not in HN but a tiny example of how cool is the project that's driving some of smalltalkers to sleep 4 hours per night.Jtalk. Credits on that go to Bromagosa

lunes, 5 de septiembre de 2011

Routing tutorials in rails 2.X

For me, one of the most confusing things in Rails is routing. The DSL, all those automagic methods, abuse of method_missing (it's starting to feel usual), and RESTful conventions, mixed with namespacing,

I've found three detailed tutorials (well, series of tutorials) that seem to explain all what's needed to get into the routing thing. Here are the links to

under-the-hood-rails-routing-dsl
under-the-hood-route-recognition-in-rails
under-the-hood-route-generation-in-rails

A couple of articles on extending routing system
monkey-patching-rails-extending-routes-1
monkey-patching-rails-extending-routes-2

Here's the starting point of a super-detailed explanation and hands on tutorial on rails 2.X routing.

beginners-tutorial-routing-in-rails-20-with-rest-part-1-of-n

There are 6 parts in this last tutorial.

Btw, both blogs seem good sources of information. Good explanation on different topics, always quite detailed, and well written. For example, here's a series of posts on AJAX (from the bottom up).

Bye!

domingo, 4 de septiembre de 2011

Jtalk tutorial. (Valid until the end of this week)





TL;DR
write this in a workspace, select, and click 'DoIt'. Instant reward.
Counter new appendToJQuery: 'body' asJQuery




You know Smalltalk, it is an object oriented programming language developed at Xerox PARC during the 70's by Alan Kay, Dan Ingalls and other brillant guys. It is known that Kay, and probably other members of the team, was born from the leg of Zeus. Jtalk is an implementation of Smalltalk that runs on top of JavaScript, developed by Nicolas Petton. It allows the use of Smalltalk for client side applications. Even more, Jtalk allows you to use the famous IDE from the Smalltalk world directly in your browser. It compiles to JavaScript, and follows Pharo, a fork of the Squeak Smalltalk implementation.

The canonical "Hello World" looks like this:

Widget subclass: #HelloWorld
instanceVariableNames: ''
category: 'Examples'
renderOn: html
"Render some html"
html div class: 'section';
id: 'headerSection';
with: [ html h1: 'Hello World' ].
view raw HelloWorld.st hosted with ❤ by GitHub

You create a subclass of Widget, and you implement the #renderOn: method. Jtalk will pass an HtmlCanvas instance that we call html in our code. This object provides some "brushes" allowing to "paint" into the html canvas by message passing. We created a div element by sending the div message to html. The div element has it's class and id attributes defined, and it contains a h1 element. Everything is performed by passing messages to the html object. Those familiar with the Seaside web framework will recognize the html canvas. After the HelloWorld class is
defined, you can see it in the browser by appending an instance to the page's body using JQuery:

HelloWorld new appendToJQuery: 'body' asJQuery


A JQuery object is created by passing the #asJQuery message to the string object 'body'. Then we pass the #append message to the JQuery object, with an instance of HelloWorld as argument. You can evaluate this expression in the Workspace and see it in action.

Another way to do the same is going to JQuery class, and send the #body message.

Where is the Counter?
If you know Seaside you'll want to look at the Counter example. I will reproduce the example from the Jtalk website, which you can find also with the IDE's class browser. It is a good example because it shows how you can write stateful applications in Samalltalk, by simply using its object system as you would do in any application:
Widget subclass: #Counter
instanceVariableNames: 'count header'
category: 'Examples'
initialize
super initialize.
counter := 0.
increase
count := count + 1.
header contents: [ :html | html with: count asString ]
decrease
count := count - 1.
header contents: [ :html | html with: count asString ]
renderOn: html
html h1 with: count asString.
html button
with: '++';
onClick: [self increase].
html button
with: '--';
onClick: [self decrease]
view raw Counter.st hosted with ❤ by GitHub

As in Seaside, the button definition is beautiful. Since the object itself holds the state of the application, you simply bind a Smalltlak code block to the onclick event, and Jtalk will take it from there.

Interacting with the DOM with JQuery and JS evaluation

As you can see, there is JQuery support provided by the JQuery class. We just used it for appending a piece of html to the body element of our page. There is support for a good part of the JQuery api, as you can see by browsing the methods implemented in the JQuery class. You can do DOM insertion, css manipulation, event handling, etc. If something you like is not implemented, you can evaluate JS code by enclosing it with the "<" and ">" characters. A wrapper for ajax is also available:

Ajax new
url: '/my_web_service/get_content';
onSuccessDo: [ :data | Transcript show: data ];
onErrorDo: [ :error | Transcript show: 'Request failed!' ];
send.
view raw simpleAjax.st hosted with ❤ by GitHub


Here we create an Ajax object and then we send some messages to it. As you can see, we use Samlltalk blocks as callbacks, this blocks are compiled to JavaScript anonymous functions for execution. There are other messages availables in an Ajax object, like #onCompleteDo. Dictionary like syntax is provided for passing additional settings to the Ajax object:

Ajax new
url: '/my/post/handler';
at: 'type' put: 'post';
at: 'data' put: 'foo';
send.


As test, I wrote a small HTTP service interfacing a CouchDb instance. I did it in Python using the small but cool Flask framework:

from Flask import Flask, abort, jsonify
from couchdb import Database
app = Flask(__name__)
database = Database("http://10.0.0.2:5984/my_database")
@app.route("/")
def index():
"""Show the Jtalk IDE"""
return render_template("ide.html")
@app.route("/get/<doc_id>")
def get_document(doc_id):
"""Lookup the document in the database and return it as JSON"""
doc = database.get(doc_id)
if doc:
response = jsonify(doc)
else:
response = abort(404)
return response
view raw simpleCouchy.py hosted with ❤ by GitHub


Please consider it almost pseudo code. You can note its very simple stuff. We serve the Jtalk DE at "/", and we provide access to the database in "/get/<doc_id>". Now, we could build a small wrapper for accessing this service:

Object subclass: #Data
instanceVariableNames: ''
category: 'Example'
get: docId onSuccess: aBlock
|smalltalk|
smalltalk := Smalltalk new.
Ajax new
url: '/get/', docId;
onSuccessDo: [ :data | aBlock value: (smalltalk readJson: data) ];
onErrorDo: [ :error | Transcript show: 'Request Failed!' ];
send.
view raw Data.st hosted with ❤ by GitHub


We provide a single method called get:onSuccess: allowing the client code to request a document and executing a callback block on the resulting data. Smalltalk blocks are constructed using brackets, and they are like anonymous functions. Temporary named arguments are declared with the :argName, and after the bar you can write any Smalltalk statement. Our onSuccessDo callback takes the data received form the Ajax request as argument. This data comes in JSON format, so we
use an instance of the Smalltalk object to translate this to a Jtalk object, and then we pass that to the block provided by the client code, which we called "aBlock".

An experiment using Rasta.js for data persistence

Rasta.js
is a very simple key/value storage service. It provides a REST API and a client library:

<script src="http://rastajs.errorjs.com/rasta.min.js" type="text/javascript">

We can use this for looking at how can we delegate execution to a JavaScript object and also for providing some data persistence to a static website.

Object subclass: #Rasta
instanceVariableNames: 'rasta'
Category: 'Example'
initialize
super initialize.
rasta := <Rasta;>.
get: aKey onSuccessDo: aBlock
rasta get: aKey value: aBlock
set: aKey with: aValue onSuccessDo: aBlock
rasta set: aKey value: aValue value: aBlock.
view raw Rasta.st hosted with ❤ by GitHub


That was easy. The Rasta class has one instance variable, called "rasta". Instance attributes are private in Smalltalk, you have to implement methods if you want to access them from the outside. But in this case, our rasta attribute is for internal use, we don't need the stinky accessors. The Rasta.js API provides two simple JS functions:

Rasta.get('age', function(val){
/* val == '100' */
})

Rasta.set('age','100', function(){
/* */
})
Since they use an upper cased name, and in Smalltalk those are reserved for classes, we have to use a special trick. Jtalk will get confused if you try to evaluate "Rasta" directly. This not happens with lower case JS names, which are available directly in the Jtalk IDE (you can try
console log: 'fooBar' for an example in the Workspace.) So, we will use our "rasta" instance attribute for storing the JS object, we use the <jsobject> notation for getting a sort of proxy object which will delegate messages in the JS one, and we can access it under the "rasta"
name in our messages. Now we can use the Rasta.js KISS service for our data storage:
database := Rasta new.
database get: 'aKey' onSuccess: [ :data | 'div#container' asJQuery append: data ].

Ok, usualy you will want to format the data. We can wrap this into a Widget subclass and implement a #renderOn: method. At this point we can put all these features together in our mind: you get a nice programming environment which promotes good code practices like layers and concerns separation, clean and readable syntax, testing facilities, and who knows
what, with an IDE accessible directly from the browser.

On code persistence

I will just say it. If you press "F5" (or "r" if you are a hacker) you will lose your code. The IDE features a "Commit category" button, which sends a PUT request with the compiled ST in the body. But as Jtalk is focused in client side coding, it is your responsability to handle the
request and save the code into the "js/" folder, next to the Jtalk library. I will show you the "almost pseudo code" thing again, with Flask and Python:

from werkzeug import secure_filename
@app.route("/<filetype>/<filename>", methods=["PUT"])
def commit_changes(filetype, filename):
"""Commit changes in the Jtalk image to disk"""
filename = secure_filename(filename)
data = request.form.keys()[0]
with open(os.path.join(UPLOAD_FOLDER, filetype, filename), "w") as fileobject:
fileobject.write(data)
return "201"
view raw commit.py hosted with ❤ by GitHub


Note that I used the secure_filename from werkzeug to sanitize the data, since I use it to build the path. You don't want to allow write to your .zshrc or similar.

Concluding

Jtalk can help you to write heavy client side applications by taking advantage of the ancient wisdom from the Smalltalk world. It still has some sharp edges but it is there for you to try it. Allows you to write stateful client code easily, and to port known and tested patterns to
the web browser, for great justice. And there is a plus. Jtalk is part of a legendary story, the Smalltalk one. After all, I have told you, these guys came from the leg of a god.

A moving target

In the couple of days that Rodrigo Bistolfi and me have been experimenting with Jtalk and writing this article (In fact he wrote most of the article), a bunch of things changed already, or are going to change shortly. For example, Capitalized Javascript objects are parsed now without problems in Jtalk. On the JQuery side, Nicolas Petton recently said that JQuery binding is going to disappear from jtalk bundle. It seems we'll be able to fetch DOM nodes directly with jtalk. So better be up to date with the jtalk git repo, because jtalk is moving fast.

Btw, there's a lot more related to Jtalk. Goran Krampe wrote jtalkc, that compiles jtalk code to js able to run in node.js. I haven't digged on that yet, but seems it also opens a shitload of possibilities... :)

Cya!

jueves, 1 de septiembre de 2011

more git workflows. Getting closer to sanity

Toady, a new article of git workflows appeared in HN. The nice thing of it is that at my workplace, we use exactly the same workflow. I just post it here for future reference

And now that we're at it, I link another git workflow related post that talks about merge --squash. A nice thing to make your history cleaner

Btw, I recently discovered a couple of interesting git man pages: gittutorial and gitworkflows. Interesting information there too.

martes, 23 de agosto de 2011

ESUG in: 2011 on: Edinburgh



ESUG 2011 is over, and I'm back from my holidays, with a couple of interesting bits about the smalltalk world, and lots of energy.

Here are the talks that impressed me most:

- Martin McClure explained Maglev smalltalk to ruby ffi. It seems maglev is more than a simple smalltalk vm. In fact it runs ruby code and smalltalk code seamlessly (at least, that's what I understood). Unfortunately, it only exist in 64-bit shape, so I couldn't try it myself. The core of the presentation though was the nice FFI that VMWare guys (former GemStoners) prepared to run Ruby code from Smalltalk.

As most of you know, Ruby is heavily influenced by smalltalk. In fact, so much that Martin and friends were able to make one object for both worlds. So String class is the same for ruby and smalltalk. Objects are the same, but the names are different, so SmallInteger for smalltalk, is fixnum for Ruby. 'super' pointer is also different, enabling to build variations in hierarchies and supporting singleton classes for ruby.

Lots of nice tricks that enable us to use ruby objects as smalltalk ones.

- Bifrost. Jorge Ressia is implementing great improvements in the reflexivity side of Pharo. Being able to treat data as code is one of the aims of bifrost. Not losing the link on logs and where a log entry comes from, or being able to hook on variable usage when debugging... Thanks to Bernat I was able to try it in my own pharo image. (Bifrost is only the framework, you have to install the programs separately)

- Jtalk. I think this was the killer talk of this ESUG. Goran Krampe and Nicolas Petton presented their (mostly Nico's) smalltalk implementation in js. Running smalltalk in browser is not only being able to write smalltalkish syntax. It means you have a full stack smalltalk in your browser. Many firebug features will come for free in Jtalk. Goran showed some experiments he's doing with node.js and jtalk compiler to js. Yes, you're able to write smalltalk for the server side. Probably I'll post more about jtalk, so keep tunned.

There were a lot of other interesting presentations, like Gerardo and Javier live garbage collection tweaks(writing garbage collectors in smalltalk and rebinding garbage collector on your live system), redline (smalltalk in your jvm) and Coral (pharo for those who can type).

It's great stuff all way down!

domingo, 21 de agosto de 2011

Cellular automatas and me

2 weeks ago I started to read Philosophy and simulation by Manuel DeLanda (thanks eskerda).

About one month ago I watched jdelgado's talk at Campus Party talking about science in science fiction, and he talks a bit about cellular automata too:


So I started to experiment a bit with cellular automatas myself, and implemented a Conway game of life in smalltalk. At first I wanted to write a very flexible (1d,2d,...nd) cellular automata engine, but once I had the 2d Game of life implemented, I realized that doing 1d things is easier if you do it with strings, or just lists (lisp lists, for example).

Well, so I implemented a 1d cellular automata in common lisp (nice exercise) and tried some interesting rules for the majority problem jdelgado mentions in his talk.

At first I thought majority problem had a defined proper solution, but searching on the internetz, it seems it's not trivial at all, and I couldn't find anything that takes me further than rule 184, that splits the list in a group of 0's and 1's.

If you want the implementation of the smalltalk GoL, ask for it (it's not that easy to paste smalltalk code on the web, you know...), or just download any already existent implementations on squeaksource, like Bernat's one.

;;; 1d cellular automata testbed
;;; Raimon Grau
;;; raimonster@gmail.com
(defun run (&optional (length 11))
(let ((population (list (gen-random-string length)))
(rules (fill-rules (make-hash-table))))
(loop while (not (equalp (first population) (second population)))
do (setf population (cons (advance-generation population rules) population))
(format t "~S~%" (first population)))
(first population)))
;;; rule 184: 101 110 00
(defun fill-rules (hash-table)
(setf (gethash 000 hash-table) #\0)
(setf (gethash 001 hash-table) #\0)
(setf (gethash 010 hash-table) #\0)
(setf (gethash 011 hash-table) #\1)
(setf (gethash 100 hash-table) #\1)
(setf (gethash 101 hash-table) #\1)
(setf (gethash 110 hash-table) #\0)
(setf (gethash 111 hash-table) #\1)
hash-table)
(defun random-elt (sequence)
(let ((seq-length (length sequence)))
(when (> seq-length 0)
(elt sequence (random seq-length)))))
(defun gen-random-string (length)
(let ((opts '(#\0 #\1)))
(loop repeat length
collect (random-elt opts))))
;; (defun neighbours (data pos)
;; (cond
;; ((= pos 0) (cons (car (last data)) (subseq data 0 2)))
;; ((= pos (1- (length data))) (append (subseq data (1- pos) (1+ pos)) (list (first data))))
;; (t (subseq data (1- pos) (+ pos 2)))))
(defun neighbours (data pos)
(cond
((= pos 0) (cons #\1 (subseq data 0 2)))
((= pos (1- (length data))) (append (subseq data (1- pos) (1+ pos)) '(#\0)))
(t (subseq data (1- pos) (+ pos 2)))))
(defun advance-generation (population rules)
(loop for elem in (first population)
for pos from 0
collect (apply-rule rules (neighbours (first population) pos))))
(defun apply-rule (rules neighbours)
(gethash (parse-integer (concatenate 'string neighbours)) rules))
;;; (concatenate 'string '(#\a #\b))
;;; adding to a hash (setf (gethash 'one-entry *my-hash*) "hola")
view raw cellular.lisp hosted with ❤ by GitHub

martes, 16 de agosto de 2011

git push -f to master and you're a dead man

Just came back from the half of my holidays, and came with a quite long TODO list.

One item of the list was a wrapper for git that avoids pushing -f the master branch.

At my new $job (yes, I changed again, you'll be noticed properly when I have more time to write), we use a minimal version of git-flow and we run tests on remote (personal) branches.

That means that sometimes, you have to git push -f to your personal remote branch, and possibly delete history. There's no problem if you do it in your personal branch, but as dumbans we err, and myself, being new to all this git fancy stuff, I was a bit worried about it.

I've come with a solution that should work fairly well and transparently. A wrapper for git that nops dangerous commands.

It's perl, and here it is.

#!/usr/bin/perl
use strict;
use warnings;
my @banned_string= qw/push -f origin (master|release.*)/;
sub banned{
my @banned = @banned_string[0..$#ARGV];
die "error" if equal(\@banned , [@ARGV]);
}
# Destructive function!
sub equal {
my ($list_a, $list_b) = @_;
return 1 unless @$list_b;
my $next_banned_param = shift @$list_a;
return 0 if !( (shift @$list_b) =~/^$next_banned_param$/);
equal($list_a, $list_b);
}
# For debugging purposes. uncomment if needed
# Don't print anything extra in stdout if you want
# vim/emacs integration to work
# open my $fh, '>>/tmp/lal';
# print $fh "@ARGV\n";
# close $fh;
banned if 1 < @ARGV;
exec '/usr/bin/git', @ARGV;
view raw git.pl hosted with ❤ by GitHub



Despite being destructive, I like the equals method, kind of lispy, but using shift as a car/cdr solution.

To make the wrapper work, rename it to 'git', make it executable, and put it somewhere in your path, before /usr/bin/git executable.

martes, 9 de agosto de 2011

Back to the future. Xerox PARC innovations.

From time to time. I spend an afternoon doing some monographic research of a great Computer Scientist, or simply people I've seen some day in TED, and would like to know more about him/her.

Sometimes it's Joe Armstrong, sometimes it's Guy Steele, but Alan Kay and friends take these afternoons more often than others.

Here are 3 Conferences by Alan Kay and one from Dan Ingalls. Those two men (and their collegues at Xerox PARC) have done probably more for our field than any other single group in the 70 years of history of CS (or call it tinkering, or computer tekne)


Alan Kay at TED talk, sharing his ideas about ideas. 2007


If you liked it (you SHOULD like it), here you can see a longer talk about Alan's last work (STEPS)

Here's Dan Ingalls talking about his work at PARC Place. Great stuff too.
And another Kay's talk about great innovations of the 60's and 70's. In XXI century, we haven't exploited many of these ideas yet.
If you know of other related talks, please, put links in comments.


lunes, 18 de julio de 2011

More presentation tools

A little reminder of a couple of tools I should try for my next presentation (tbh, I don't have any presentation in near future, but..)
We'll see when someone writes org-mode + shower helpers.

sábado, 16 de julio de 2011

open rails files from console to $EDITOR

You're in the console, run rake test, and appear a bunch of file paths cluttered with line numbers, colons, and no spaces between them. Well, lest turn the no-space-between them thing in a WIN for us.

Errors and failures show in different formats when running tests (not a very *intelligent* thing if you ask me, but...). Well, a simple regex and we have 'pe' , powered-emacslient, path-edit, or whatever. In my shell, double click any of the two versions and 'pe ', and you're sitting again on your editor. placed in the correct line.

.. app/models/bar.rb:88:in ..
.. [test/unit/foo_test.rb:9]: ..

#---e-----
#!/bin/zsh
emacsclient -n "$@"
#---pe----
#!/usr/bin/perl
my ($file, $line) = shift =~ m/\/?(.*):(\d+):?/;
system 'emacsclient', '-n', "+$line", $file ;
view raw e_and_pe.pl hosted with ❤ by GitHub


'e' is the original emacsclient script I use for other files. Unifying both scripts in one is left as exercise to the reader.

I want to spend an afternoon hacking a urxvt plugin to fetch for strings ressembling paths, and be able to open them using just keyboard, but that's a thing for another day.

jueves, 14 de julio de 2011

Sending links when you cannot send files.

I've been reviewing my ~/bin directory and felt like sharing some of the little scripts there.

Today, here's a little Perl script that helps me when having to give a file (screenshot or something) to someone @work. Most people do it by mail, or using jabber protocol. Unfortunately, emacs-jabber does not allow sending nor receiving files, and opening mail client and attaching files is waaay to slow and boring.

The way I work with this situation is having a simple http server in my computer, and moving the file there. then, I paste the link to my coworker, and he/she just has to click it and download.

The http server lives inside emacs. Oh yeah, that's irrelevant. But I had to say it.

Well, here's a script I wrote in 2 minutes.

#!/usr/bin/perl
use strict;
use warnings;
use Clipboard;
use Digest::MD5;
use File::Copy qw(copy move);
my $par=shift;
open my $fh, $par or die "no parameter!";
binmode $fh;
my $dest_dir="/home/rgrau/public_html/";
my @output = grep {/inet addr/} `ifconfig`;
$output[0] =~ /inet addr:([^ ]*) /;
my $server="http://$1:8080";
my ($ext) = $par =~/^.*(\.[^.]*)$/;
my $md5 = Digest::MD5->new->addfile($fh)->hexdigest;
copy($par, "${dest_dir}${md5}${ext}");
Clipboard->copy("$server/${md5}${ext}")
view raw publish.pl hosted with ❤ by GitHub


Hashing the name is to avoid name guessing. I think I got this idea from a Mark Fowler's post that was doing something like this with dropbox.

miércoles, 6 de julio de 2011

Snapshots motherf*cker, do you speak it?


Today, I'll just snap a recipe for a use case that starts to crop up when evolving from a total git beginner to not-so-noob-git-user. git reset

Here's the diagram:

git reset
+-------------+ git reset +-----------+
| | --soft | |
| index | HEAD^ | repo |
| |<------------+ |
| | | |
+-----+-------+ +-----------+
| git reset [file]
v
+-------------+
| working |
| directory |
| |
+-------------+


Ok, now screw it.

The main problem when thinking about how git works is thinking in the wrong way. You've been told hundreds of times that git works differently from EVERY other versioning system around, and you keep forgetting these concepts every now and then.

The diagram before is a diagram of where git moves your changes when you do a given reset command. git reset --soft foo moves the changes from commit 'foo' till HEAD to the index.

YOU'RE THINKING IT WRONG.

Remeber that you've been told that git records only snapshots? Well, think about it. When you want to reset your repo to the past, if you have a clean working directory and index. HEAD,index and wd are all in the same state. That means that All trees contain the same. THE SAME. If you are thinking that your wd has some files, that the index is empty (Delta is null) and same (or kind of) for the repo, you're thinking it WRONG again.

Now, if you go and look git help reset, and this MJD's post about git reset.

Then it's kind of easy to understand what it does, and in which state will leave your repo, index and ass.

(take the italics notes as if you just reseted the most recent commit, if you reset to older ones, all changes are accumulated)
  • git reset --soft just updates your HEAD. Changes are in the stage, ready to be commited without that nice 'fdsajflkdsajflkasdf' commit message. You're in the moment before you commited.
  • git reset --mixed updates your HEAD and your index accordingly. That means that probably, if you're reseting to past commits all changes from the target commit till now will be only in your wd. You're in the moment before you added files.
  • git reset --hard updates everything. You're in the moment after you commited the commit (O RLY?) so you lost everything you did after the commit.

Btw, Take all this post with a grain of salt. I just had an 'AHA!' moment I had to share. Probably it's not *very* technically accurate. I haven't even tried what happens on detached heads and other bizarre situations... yeah, I'm a sucker.

man git-reset contains lots of tables and info, but IMHO, naming the states of files A B C D lead to harder understanding that if they'd have been D C B A.

And now, a doubt for the lazyweb:
git reset hard does not allow you to recover your state. gitk --all does not show anything from HEAD on. but git reflog does show it. And I'd swear gitk --all worked 2 days ago....

Addendum: Here's a great article on git reset that appeared a week after my finding. Really well explained, with graphics, tables and everything.

domingo, 3 de julio de 2011

El trabajo del futuro


Via RaulGB, veo que hay empresas tan avanzadas a su tiempo, que vienen del futuro, como la rubia de la lejia, o Levi Strauss con un Delorean, o H.G.Wells.

Me guardo la oferta, espero 3 años, me pillo una time machine, que seguro que estaran inventadas por entonces, y vuelvo a por el curro.

Esperad mi llamada el martes que viene. De vuestro tiempo.

sábado, 2 de julio de 2011

Resize window in emacs

I use emacs as much as I can. That's not really news, is it?

One of my use cases for emacs is chatting with friends. I use erc for IRC, and emacs-jabber for everything else.

One thing that annoys me a bit is that when my screen is split in two and want to shrink a bit one of the two windows.

There's c-x - (shrink-window-if-larger-than-buffer) but it's only useful for a handful of situations (IMHO)

Here is a little function I wrote to shrink a window to selected region. I find it useful to narrow windows to functions, paragraphs, or just narrowing a chat window to just 5 or 10 lines.

(defun shrink-window-to-region ()
(interactive)
(let
((window-lines (count-lines (window-start) (window-end)))
(region-lines (count-lines (region-beginning) (region-end))))
(shrink-window (- window-lines region-lines))))


Select a region, and run it. Then c-l to recenter accordingly.

I mainly use it as a more visual narrow-to region.

Have fun

lunes, 27 de junio de 2011

read-only weekend

Pretty nice weekend:

Thursday night, a 'Gifted' concert with many of our friends attending.
Great St.Joan party.

From Friday to Sunday I didn't program anything but read a couple of
books. Yes, two. It's true both were quite easy reads and not very long.

One of them is OReilly's 'The productive programmer'. I found the
book a really easy read, but maybe it's beacause I already knew most
of the tricks. In fact I already knew I'd already know most of the
tricks. The second part of the book, though was a bit more abstract,
and I could make some use of the info there.

Points I found most interesting:

- Make a living doc. (From commit logs to wiki, for example)

- Learn to FOCUS. (I'll search for csikszentmihalyi's books)

- Composed Method and SLAP.


The other book I skimmed is more a long article than a book: Git Magic, by Ben Lynn.

It's a pretty nice source of info on git. Really concise and to the
point. Mostly beginner, but also contains some advanced tricks (with
the use cases explained), and a chapter on the git low-level stuff
(remember git from the bottom up?)

miércoles, 22 de junio de 2011

Don't quit emacs by accident


Today I read a blogpost by en emacser blogger (tsengf) about quitting emacs accidentally.

He writes a function to avoid closing emacs by accident when there's an opened file that belongs to any of your projects.

My approach is somewhat different:

Usually, when I have emacs opened, I have some processes running within it. That makes emacs warn me when I press c-x c-c by accident, and asks for confirmation (the same way as if I had unsaved buffers)

Anyway, sometimes my muscle memory screws everything, and presses 'y' without asking my conscious mind.

Here are a couple of solutions that work to some extend.

The first one is the radical one. Just do not shut up emacs. Yes, as strange as it seems, I rarely have to close emacs while my computer is on.


global-unset-key c-x c-c


Then you have to exit emacs with the name of the whole command save-buffers-kill-terminal


As a not-so-radical solution, my bet is for desktop-save to save every session in your home directory.


(defun desktop-save-main ()
(desktop-save "~/"))
(add-hook 'kill-emacs-hook 'desktop-save-main)


Then, if you want to recover the state of the previous session, you have to eval (desktop-read) or (desktop-read "~/") if you aren't on your home dir.

If you had sql sessions, erc sessions, or any other comint buffer... well... you lost them.

PS: If you happen to know how to make this blog/post appear on the emacsen planet, please comment, or mail me, or twitt it to some emacs aggregator.... or just twitt the post FEED ME MOAR RSS's!

jueves, 16 de junio de 2011

sleepsort for the lulz

Today I discovered a programmers' BBS on 4chan (It hit HN's front page).
There was a post talking about a sorting algorithm that the author called it 'sleepsort'
I couldn't believe I didn't thought of it before. In fact in a past post talking about Parallel::Iterator, I played with timers too.... I was sooo close :)

#!/bin/bash
function f() {
sleep "$1"
echo "$1"
}
while [ -n "$1" ]
do
f "$1" &
shift
done
wait
view raw sleepsort.bash hosted with ❤ by GitHub


Lots of lols reading the full thread, with comments, optimizations, translations to other languages and puns there.

For example:

- complexity of the algo: O(highest_value_in_input)

- 40: Someone email this to Knuth.
- 41: >>40. Knuth doesn't do email anymore


Have fun.

martes, 14 de junio de 2011

vim.orthogonality > emacs.orthogonality

I already mentioned this same thing in other posts, but well, today I stumbled upon another example of it.

Vim is like a unix commanline, lots of little commands you can combine one to each other. It has the cognitive style of linux command line

bufdo,argadd,argdo... These are the 'pipes' of vim. multiplicity enablers that add functionality,commands and power in an exponential way.

When writing ReST docs to take notes at university, I used Vim, and I got used to underline titles with an add-hoc sequence I made up (yank line,paste,visual line, replace, char) . Vim doesn't need a specific command for it, because it's immediate, and like most vim combos, it's like talking to it in a funny slang.

On the other corner, emacs: as part of emacs-goodies (ubuntu package with a bundle of emacs plugins) There's under.el. A plugin that exports 'underhat-region'. A function that underlines a region with caret characters. The bad thing of underhat-region is that it's not parametrizable, but that's not the point. The fscking point is that in emacs you end up stumbling upon functionalities that are already there as commands, but probably sunken among zillions of other commands.

I'm more a vim-style guy myself, but couldn't resist emacs+vimpulse combination. I think I'm sold.

martes, 7 de junio de 2011

PAIP, special edition




I recently bought a copy of PAIP in dead tree format (as usual, a used one). When I received it, I was a little worried about the state of the book (it was expensive enough to be worried about it). I opened the package, glanced it and seemed pretty good. Nearly unused.

But when I opened it... OMG! The fist page contains a note from Peter Norvig!

FUCK YEAH!

lunes, 6 de junio de 2011

js can be fun(ctional) too. A new hope

Reviewing my latest gists, I re-discovered one in which I copied a js snippet that implemented foldr, one of those great higher order functions. As a proof of concept, I implemented some of the functions on 'Why functional programming matters' paper. In fact, I reimplemented nearly all builtins.scm (from my Half Assed Scheme implementation)

// foldr function shamelessly stolen from
// http://blog.thatscaptaintoyou.com/haskells-foldr-in-javascript/
// Added 'any' function for my own needs. More at http://puntoblogspot.blogspot.com/
function foldr(fn, ult, xs) {
if (xs.length == 0) {
return ult;
}
if (xs.length == 1) {
return fn(
xs[0],
ult
);
}
else {
return fn(
xs.splice(0, 1)[0],
foldr(
fn,
ult,
xs
)
);
}
}
function any(needle,haystack){
return foldr(
function(a,b){
return (b || (a==needle))
},
false,
haystack
)
}
any('hola' , 'hola ke tal'.split(' '))
view raw any.js hosted with ❤ by GitHub


I recently took a quick look at coffeescript, and it seems very promising. Unfortunately, I didn't even try it (just the online interpreter). Maybe when I try rails 3.1

miércoles, 25 de mayo de 2011

Undo layouts in emacs

Once you're used to being able to undo and redo window layouts in your windowmanager (hello ratpoison!), You feel the need to have this same feature everywhere.


;;; winner-mode
(winner-mode 1)
(global-set-key (kbd "C-x 4 u") 'winner-undo)
(global-set-key (kbd "C-x 4 r") 'winner-redo)

martes, 24 de mayo de 2011

Slime configuration for common lisp

I recently bought a dead tree copy of Norvig's Book PAIP, and plan to dig harder on common lisp environment.

To set up a correct environment, there's emacs,slime and an implementation of common lisp. sbcl is my choice, for no big reason. It's just one of the free implementations.

Slime configurations are endless, but here's a decent one that mostly works for me.

(add-to-list 'load-path "/home/kidd/programmingStuff/slime/slime/")
(add-to-list 'load-path "/home/kidd/.emacs.d/")
(add-to-list 'load-path "/home/kidd/programmingStuff/slime/slime/contrib/")
(autoload 'paredit-mode "paredit"
"Minor mode for pseudo-structurally editing Lisp code." t)
(add-hook 'emacs-lisp-mode-hook (lambda () (paredit-mode +1)))
(add-hook 'lisp-mode-hook (lambda () (paredit-mode +1)))
(add-hook 'lisp-interaction-mode-hook (lambda () (paredit-mode +1)))
;(load (expand-file-name "~/.quicklisp/slime-helper.el"))
(require 'slime)
(setq inferior-lisp-program "sbcl")
(slime-setup '(slime-fancy slime-asdf slime-banner))
(setq slime-net-coding-system 'utf-8-unix)
(setq slime-autodoc-use-multiline-p t)
(defun slime-repl-quickload ()
(interactive)
(let* ((completings
(slime-repl-shortcut-eval
`(cl:mapcar 'ql-dist:system-file-name (ql:system-list))))
(system (completing-read "System: " completings)))
(slime-repl-shortcut-eval-async
`(cl:progn
(ql:quickload ,system)
(cl:format t "; System ~a loaded.~%" ,system)))))
(defslime-repl-shortcut slime-quickload ("quickload")
(:handler 'slime-repl-quickload)
(:one-liner "Quickload a Lisp system."))
;; Esto permite a SBCL cargar sus módulos contrib desde imágenes (cores)
;; extraoficiales.
;;(setenv "SBCL_HOME" "/usr/lib/sbcl/")
;; Loop indentation
(setq lisp-simple-loop-indentation 2
lisp-loop-keyword-indentation 6
lisp-loop-forms-indentation 9)
(defun run-clisp ()
(interactive)
(slime "clisp"))
(defun run-sbcl ()
(interactive)
(slime "sbcl"))
(defun run-sbcl-gtk ()
(interactive)
(let ((core (expand-file-name "~/.sbcl/core/sbcl+gtk.core")))
(slime (concat "sbcl --core " core))))
;;;; Paredit
(require 'paredit)
(add-hook 'emacs-lisp-mode-hook 'enable-paredit-mode)
(add-hook 'scheme-mode-hook 'enable-paredit-mode)
(add-hook 'lisp-mode-hook 'enable-paredit-mode)
view raw .emacs hosted with ❤ by GitHub


Ah, there's a surprise in the book. I'll show you in a future post :)

lunes, 23 de mayo de 2011

Smalltalk tutorial on IRC

Last week at #emacs-es on Freenode I did a very-short-and-introductory-hands-on-workshop on smalltalk. Just in case you know spanish, here's the log, with names removed to protect the guilty.

<rgrau> holas
<rgrau> user1: no se si estabas cuando lo comente, que el modo de interaccion guay con smalltalk esta superverde, y aun no da para un tuto, ni nada
<rgrau> si quereis, lo que podemos hacer es algo intermedio: hacemos el tutorialillo de smalltalk en el entorno smalltalk
<rgrau> y si os mola, le metemos mano al modo
<user1> claro, lo que tu veas :)
<user1> pero cuando?
<rgrau> cuando querais
<rgrau> esto si que se puede hacer en un ratito
<rgrau> en cualquier momento
<user1> yo suelo tener tiempo, asi que cuando user3 diga :)
<rgrau> user1: has visto lo ultimo de technomancy? una forma de instalar slime+clojure+lein en un momento
<rgrau> 2 comandos
<rgrau> y funcionando
<rgrau> me gustaria aprender algun fw web de clojure
<user1> ni idea
<rgrau> http://technomancy.us/149
<user1> pero clojure..
<user1> soy muy reacio
<rgrau> por?
<user1> por ir sobre java
<rgrau> pfff, ya... pero al nivel del programador, tanto se debe notar?
<rgrau> esque parece el lisp moderno al k se tiende
<user1> no es que se note,
<user1> para hacer tus cosas, puede funcionar
<user1> pero es una dependencia que yo preferiria no asumir
<user1> te imaginas proyectos tipo GNUPDF sobre algo asi?
<rgrau> ah, ya
<user1> no se, es algo que no me deja tranquilo
<user1> evidentemente, en el curro o algo asi, yo lo usaria antes que java, para eso mola
<rgrau> yo me referia algo para currar
<user1> pero no es algo que me molestaria mucho en difundir para ser
<user1> el nuevo python o algo asi
<user1> que es lo qe parecen pretender
<user1> por cierto rgrau
<user1> hoy envie los papeles de erasmus a irlanda ya
<rgrau> aha
<user1> ya cuando respondan sabre seguro si voy o no
<user1> bueno, yo me animo tambien a cuando querais dar la charla de slime
<user1> o taller, mejor dicho
<user3> Ya estoy
<user3> hola :)
<user3> Pues eso que surgió la idea de dar unas mini charlas aquí, y decian rgrau y user1 que a lo mejor te interesaba escucharlas, y aportar con todo lo que sabes.
<user2> bien
<user3> a ver si ellos te comentan
<user2> user1: ya me ha comentado alog ..
<user2> algo
<user2> aunque no mucho
<user3> ahh
<user2> user6: cocinillas ...
<user3> Y el viaje que tal
<user2> bien, algo cansado, ahora en uk amanece muy temprano
<user3> ah, que estas en UK!
<user2> ahora ya no, he estado esta semana pasada en UK
<user2> ya estoy en casa
<user3> ahm
<user1> nas :)
<user1> eso, rgrau propone contarnos algo de smalltalk, yo puedo contar algo de slime
<rgrau> hey, buenas
<user2> yo quiro smalltalk en el ipad
<user2> quiero*
<rgrau> jej
<rgrau> pues la idea era presentar un modo de smalltalk para emacs, pero el que hay para gnu-emacs esta muy verde, y hay un tipo k esta haciendo uno, que pinta bien, pero hace una semana escasa k lo empezo
<rgrau> y hemos dicho de presentar smalltalk, asi a la brava
<rgrau> y ya veremos que hacemos
<rgrau> smalltalk es interesante cuanto menos
<user1> claro :) si lo haces en plan taller, dejando tiempo para probar cosas, genial :D
<user3> Pues ponemos un día que podamos
<user3> nos dices el software necesario o instalamos sobre la marcha =)
<user1> yo cuanto antes mejor, que si no me meto en los examenes
<rgrau> hoy a las 23?
<rgrau> :D
<user3> Por mi si. Cualquier dia es bueno. Asi paro un pco =)
<user1> venga
<user1> :D
<rgrau> ouyeah
<rgrau> ah, los que useis ratpoison, teneis algun otro wm porahi?
<user2> pharo ?
<rgrau> pharo (la implementacion que usaremos) no se lleva nada bien con ratpoison
<rgrau> oui
<rgrau> http://www.pharo-project.org/home
<rgrau> ostias, han sacao la 1.2.1
<user2> jejeje
<user3> rgrau, de los atilados, durante un tiempo usé wmii, stumpwm, y awesome
<user1> yo estoy tirando de gnome jaja
<rgrau> creo que rp es el unico que no se lleva bien. stump ok, musca ok, awesome creo k tb
<user1> es que como no porgramo ultimamente..
<user1> rgrau: esta en debian?
<rgrau> creo que no, pero no hay problema, hay un descargable (one click image)
<rgrau> que es cosa de unzipear y esta autocontenida
<rgrau> pues tios, voy a hacerme algo de comida, y luego miramos algo de eso ,aunque sea solo entorno y tal
<rgrau> va bien chicos?
<user1> si, yo voy a instalarlo ya
<user1> asi adelanto
<user1> hasta luego
<user1> 23 aqui
<rgrau> yep
<rgrau> si veis a alguien k entra, se lo comentais
<user2> http://astares.blogspot.com/2011/05/squeak-forks.html
<rgrau> ostia, openqwak
<rgrau> aun no lo he probao
<user1> me recuerda a factor el entorno
<user1> (por las screenshots)
<user1> rgrau: crees que es dificil implementar smalltalk? algo de juguete quiero decir
<user1> no hace falta compatibilidad, solo la idea
<rgrau> bueno, la gracia de smalltalk es el sistema de objetos
<rgrau> clases metaclases
<rgrau> y todo esto
<rgrau> la sintaxis no es dificil, pero el bootstrap no tengo claro como se haria
<rgrau> el lenguaje en si , es muy sencillo
<user3> rgrau: Descargando faro, es lo que hace falta¿?
<rgrau> sips
<user1> user3: ni instalacion, es standalone
<rgrau> la one-click imaga
<rgrau> image es la buena
<rgrau> (para nosotros)
<rgrau> bueno, reboto a ubuntu
<rgrau> hasta ahora
<user3> Pharo installed :)
<rgrau> ouyeah
<rgrau> por mi le damos candela ya mismo
<rgrau> sino esperamos, no hay problema
<user3> Esperamos que vuelva user1
<rgrau> sisi
<user1> buenas
<user1> rgrau, user3: estais ya?
<user3> si
<user1> cuando veais empezamos
<rgrau> yep
<rgrau> user4: y paco?
<user3> lo he avisado, por si se apunta
<rgrau> holas user5. user5 emacseros, emacseros user5 :)
<user3> M-x Bienvenido user5
<rgrau> bueno, pues vamos palla, no?
<user3> Pacolinux viene
<rgrau> aha
<rgrau> ok. esperamos
<user5> Buenas rgrau, user3
<user3> Pues, cuando quieras rgrau
<rgrau> oks. pues vamos palla
<rgrau> oks, usaremos pharo
<rgrau> 1.2.1, que veo que es la ultima
<rgrau> (paco ya se apuntara)
<rgrau> os cuento un poquito de historia sobre todo el tema
<rgrau> smalltalk es el 1r lenguaje oop orientado a clases.
<user3> Le guardamos log
<rgrau> antes de st, los mismos del XEROX PARC, crearon self, que es un lenguaje oop con prototipos
<rgrau> no lo he catado, pero creo que no era oop puro
<rgrau> entonces smalltalk fue lo que revoluciono la escena
<rgrau> oops tel
<rgrau> back
<user5> wb
<user3> :)
<rgrau_> joer
<rgrau_> me cai
<user1> :D
<rgrau_> estoy live?
<rgrau_> bien
<rgrau_> pues eso, que esos mamaron de las lisp machines, donde todo esta vivo
<rgrau_> y smalltalk es un lenguaje + el entorno, que esta hecho en el mismo lenguaje
<rgrau_> es como elisp y emacs
<rgrau`> arrancamos pues pharo
<rgrau_> pharo.sh
<rgrau`> y se ve un escritorio
<rgrau`> verdad?
<user3> si, con una ventana de bienvenida
<rgrau`> sip. una de las novedades de smalltalk era la gui. fue de los primeros sistemas con ventanas solapables, entorno grafico y uso intensivo del raton
<rgrau`> (cosas que en este canal, no nos hacen mucha gracia necesariamente, :p )
<user1> ( cuando preguntas, por defecto digo que si :P os sigo, pero para no interrumpir mucho )
<rgrau`> (oks)
<rgrau`> abrimos un workspace
<rgrau`> clicando en el fondo de pantalla
<rgrau`> y workspace
<rgrau`> esto es un buffer donde probar cachitos de codigo, o interactuar con el sistema
<user1> yep, como un *scratch* :)
<rgrau`> de hecho, cualquier sitio donde puedas meter texto, sirve para interactuar con el sistema, pero los WS son para ello
<rgrau`> exacto
<user3> Un interprete
<rgrau`> la cosa es que todo el sistema esta interpretando continuamente
<rgrau`> probamos, por ejemplo de meter 4 + 3
<rgrau`> seleccionamos con el raton, boton derecho,
<rgrau`> y vemos varias opciones
<rgrau`> do it, que ejecutara la operacion, pero no habra feedback, pq no es nada del tipo Window open
<rgrau`> sino k retornara 7 y punto
<rgrau`> osea, print it es lo ke tenemos k hacer
<user1> hm, que pongo entonces exactamente?
<user1> 4 + 3
<user1> print it
<user1> ?
<rgrau`> seleccionar , boton derecho y darle al print it
<user3> 4 +3, seleccionar con el ratón
<user1> ah vale!
<rgrau`> ahora vamos a mirar algo de lenguaje
<user1> una pregunta :) en el menu, al lado de cada accion aparece una tecla
<rgrau`> sips
<user1> supongo que es para atajo del teclado, como lo invoco?
<rgrau`> alt-tecla
<user1> bien :)
<rgrau`> o control-tecla
<rgrau`> no me acuerdo bien
<rgrau`> i alt-p hace el print de la linea
<user1> ambos parece
<rgrau`> te ahorras seleccionar
<rgrau`> ok. en smalltalk, todo lo que veis ahi son objetos
<rgrau`> todo significa TODO TODO
<rgrau`> la ventana, el parser el compilador, los pixeles
<rgrau`> ....
<rgrau`> y estan vivos, y accessibles
<rgrau`> las clases tb son objetos
<rgrau`> y tienen metaclases... que tb son objetos
<rgrau`> ... etc...
<rgrau`> vamos a por el lenguaje y luego jugamos mas con las metaclases
<rgrau`> solo hay objetos, mensajes que se les mandan, y alguna cosita extra (la asignacion no es un mensaje)
<rgrau`> lo que en java seria obj.meth(attr1,attr2)
<rgrau`> en smalltalk se hace:
<rgrau`> obj meth:attr1 and:attr2
<rgrau`> la cosa es que se intercala el nombre del mensaje entre los parametros
<rgrau`> solo hay 3 tipos de mensajes distintos. los unarios, que no tienen parametros:
<rgrau`> 4 factorial
<rgrau`> los binarios, que, por conveniencia los montaron, son normalmente las operaciones matematicas
<rgrau`> 4+3
<rgrau`> los de palabra clave, que son los que tienen varios parametros
<user1> rgrau`: unario no es 4 parametro?
<user1> un*
<rgrau`> nope. los unarios son los que no tienen parametro. digamos que el metodo con un solo objeto ya tiene bastante
<rgrau`> (el self)
<user1> ah vale
<user1> que el self se recibe siempre y no se cuenta
<rgrau`> sips
<user1> ok ahora pillo
<user1> 4 factorial
<user1> factorial es el mensaje y se envia al objeto 4
<rgrau`> en st, no existe el metodo que no este en ninguna clase
<rgrau`> sips
<user1> y en 4+3
<rgrau`> self es 4
<user1> cual es el objeto y cual el parametro?
<user1> el primero, ok :
<user1> :)
<rgrau`> los de palabra clave son los que tienen varios parametros
<rgrau`> OrderedCollection new add: 'hola'
<rgrau`> esto lo que hace es:
<rgrau`> OrderedCollection new
<rgrau`> que devuelve un nuevo array
<rgrau`> y se le aplica el metodo add: con el parametro 'hola'
<user3> Cual es el mensaje en esa sentencia, new y add?
<rgrau`> hay 2 mensajes distintos
<rgrau`> new que se manda a la clase OC
<rgrau`> y add que se manda a la instancia que sale de (OC new)
<user1> entonces, es mas o menos concatenativo no?
<user1> en el sentido de que podrias hacer
<user1> 3 factorial factorial
<rgrau`> sip, si son unarios, no problem
<rgrau`> para anidar keyword messages tienes que tirar de parentesis
<rgrau`> OC new add:'hola' add:'adios'
<rgrau`> esto, sin parentizar se refiere al mensaje add:add:
<rgrau`> que puede existir
<rgrau`> pero si queremos montar nuestro orden de evaluacion,
<rgrau`> (OC new add:'hola') add:'adios'
<rgrau`> esto contando que add: devuelva la orderedcollection. si resulta que da alguna otra cosa, nos jodieron (hay formas de salvarlo)
<user3> seria un mensaje add al add?
<user3> el ejemplo anterior sin parentesis
<user1> rgrau`: and: ahi es especial para meter mas argumentos o
<user1> es una artimaña y realmente es un mensaje tambien? :) solo curiosidad
<rgrau`> como? no te pillo
<user1> si, dijiste que
<user1> obj.meth(attr1, attr2) = obj meth:attr1 and:attr2
<rgrau`> nope, and era por decir algo
<user1> ah, entonces, como se le pasas 2 argumentos a un mensaje? :)
<rgrau`> Dictionary new at:'clave' put: 'valor'
<user1> ah vale
<user1> el mensaje en si sabe cuantos parametros recibe
<rgrau`> sip
<user1> entonces es
<rgrau`> por eso, si no parentizas, no sabes cuando empieza uno y acaba otro
<user1> obj.meth(attr1, attr2) = obj meth attr1:value attr2:value mas bien no?
<user1>
<rgrau`> bueno, la palabra meth como tal no existe
<rgrau`> a := Dictionary new .
<rgrau`> a at:1 put:'val'
<rgrau`> los mismos nombres que les das a los parametros tienen que servir para describir que hacen
<rgrau`> y que hace el metodo en si
<user1> hm, a ver si me entero, estoy un poco lento :D
<rgrau`> jej, tranki
<rgrau`> espera, k montamos algun ejemplillo
<user1> me estas diciendo entonces que, los metodos no tienen nombres sin oque
<user1> segun que parametros estas usando y como, se determina cual es?
<rgrau`> bueno, en cierta manera si, pero no es tan raro. los unarios si que parece que tengan nombre, no?
<rgrau`> pero es lo mismo
<user1> por eso :)
<rgrau`> at:put: es el nombre del metodo
<rgrau`> y sabes que tiene 2 parametros pq hay 2 ':'
<rgrau`> y sabes donde van
<user1> ah, esta chulo. Va la verdad que asi se ve muy claro de donde viene el termino 'mensaje'
<rgrau`> :)
<rgrau`> seguimos, y luego quedara claro
<user1> no doy mas la lata :D a continuar
<rgrau`> smalltalk tiene solo 6 palabras reservadas
<rgrau`> eso significa que for,if,..... eres libre de usarlo como quieras
<rgrau`> y ahi viene el truco
<rgrau`> if, es un mensaje
<rgrau`> implementada en la classe Boolean
<rgrau`> con esto y bloques, que son como lambdas, se monta todo
<rgrau`> true ifTrue:[print 'ouyeah']
<rgrau`> estamos? estamos flipando?
<rgrau`> xD
<user3> me:2ªopción
<user1> igual que en postscript, si
<user3> continuemos :)
<user1> voy a poner [print 'uyeah'] y a inspeccionarlo :D
<rgrau`> es un BlockClosure
<user1> me lo resalta mal
<user1> el ] final
<rgrau`> el separador entre sentencias es el punto
<rgrau`> puede ser que sea por algo k tenias antes en el ws
<rgrau`> ok, vamos a otra cosa, k es la clave de currar en smalltalk
<rgrau`> menu -> system browser
<rgrau`> eso es el browser de codigo. ahi puedes acceder a todo lo que esta corriendo en la imagen
<rgrau`> aqui no hay archivos
<rgrau`> todo el codigo esta ahi
<rgrau`> si buscais en el textbox de arriba Boolean
<rgrau`> vereis en la segunda ventanita, que Boolean tiene 2 subclases , true y false
<rgrau`> si?
<user3> si
<user3> Pertenece a Kernel-objects
<rgrau`> exacto
<user1> un segundo, yo lo lo encuentro
<user3> La tercera ventana que sería?
<rgrau`> user1 estas en el system browser?
<user1> ahora
<user1> fallo mio :)
<user3> Muy curioso
<rgrau`> la tercera son los protocolos
<rgrau`> ok, pues os cuento, Boolean tiene estas 2 subclases, que ademas son singleton, osea, solo hay un true y un false en todo el sistema
<rgrau`> (1=1) ifTrue:[algo]
<rgrau`> en el primer paso de la 'reduccion'
<rgrau`> hay el mensaje binario
<rgrau`> 1=1
<rgrau`> que devuelve true
<rgrau`> y despues se hace el
<rgrau`> true ifTrue:[algo]
<rgrau`> picad en true
<rgrau`> y en la ultima columna buscad ifTrue
<rgrau`> y vereis el codigo
<rgrau`> y piel de gallina
<rgrau`> es trivial implementar estructuras de control
<rgrau`> aBlock value evalua aBlock
<rgrau`> es como meter parentesis en lisp
<rgrau`> o un eval
<rgrau`> pillais el asunto?
<user1> si claro
<user1> se aprovecha de la especializacion en las clases para delegar la evaluacion condicional al sistema :)
<user3> Como se ve el código de ifTrue: ?
<rgrau`> clica en True
<rgrau`> y luego ifTrue en la ultima columna
<rgrau`> y abajo saldra el codigo
<user3> ah, lo de abajo :D
<user1> y en Boolean es self subclassResponsibility
<rgrau`> exacto
<user1> que claramente lo deja a eleccion de la especializacion, guay
<user1> aunque pensaba que eso seria automatico :)
<rgrau`> si una clase tiene un subclasResponsability no puedes instanciarla
<user1> el orden de evaluacion que es de mas general a mas especifico?
<rgrau`> nope, va de abajo arriba, el subclassR.... es solo para indicar que si llega ahi, error
<user1> ah!
<rgrau`> subclassResponsability esta implementado en la classe de mas arriba
<rgrau`> y saca un error
<user1> guay :)
<rgrau`> todo da vueltas alrededor de la estructura de clases
<rgrau`> se puede decir que sabeis el 90% del funcionamiento de smalltalk
<rgrau`> ifTrue de False, devuelve nil y a tomarporsaco
<user1> el ^ de ^nil
<user1> merece algun comentario?
<rgrau`> return
<user1> ok
<rgrau`> normalmente se devuelve lo ultimo evaluado
<rgrau`> pero ^ es explicito
<user3> ^ que le indica?
<user1> ea, yo he practicado un poco con operaciones logicas and: y or: ya
<rgrau`> y lo chulo es que si quieres hacer booleanos de 3, subclaseas Bool con algo tipo 'undef' o alta impedancia
<user1> muy bonito
<rgrau`> y todo rula
<user1> rgrau`: aqui los objetos tienen atributos, o solo existe el objeto y los mensajes?
<rgrau`> tiene atributos
<rgrau`> ahora probamos algo
<rgrau`> id al menu i abrid un terminal
<rgrau`> tools->transcript
<rgrau`> en el workspace probaremos un 'print'
<rgrau`> Transcript show: 'hola'. Transcript cr
<rgrau`> show es un metodo de la classe Transcript
<user1> eso donde?
<rgrau`> en el workspace
<rgrau`> una vez tengas el transcript abierto
<rgrau`> user5: tu interrumpe si quieres, eh
<rgrau`> cr es un metodo que inserta un carryreturn
<user1> voy a hacer una prueba
<rgrau`> hay un poco de sintax sugar, para evitar repetir Transcript
<rgrau`> Transcript show:'hola';cr
<user1> vale, el terminal es unico en el sentido de que si abres mas
<user1> la salida va a todos :)
<user3> Lento estoy, ahora pillo de true, e ifTrue :D
<rgrau`> el puntoycoma sirve para mandar metodos en cascada al objeto original
<user1> guay
<rgrau`> Transcript show:'hola';cr;show:'adios'
<rgrau`> ahora, si os parece, creamos un par de clases
<user1> jeje, funciona al extremo, me gusta
<user1> sin excepciones
<rgrau`> y ya habremos dado la vuelta al primer nivel
<user1> 4+3;+2
<rgrau`> sisi, es totalmente puro
<user1> => 6 :-)
<rgrau`> la logica que hay detras es unicamente la que os he contado
<rgrau`> no hay mas
<rgrau`> es genial en su simplicidad
<rgrau`> y si pasas de objeto->clase a clase->metaclase, funciona por el mismo dispatching
<user1> balance simplicidad-potencia, si
<rgrau`> se sirven de ellos mismos
<user1> forth es mas simple pero no hace tanta magia :)
<rgrau`> creamos un par de clases pues?
<user1> espera, voy a sorprender a vejeta
<rgrau`> oki
<rgrau`> :)
<user3> a verrr =)
<user1> no tira :D
<user1> queria hacer
<rgrau`> que querias provar to host
<user1> 1 :to 100 :do [ Transcript show:'foo';cr ]
<user1> pero el bloque acepta algun argumento o algo y tengo que capturarlo
<user1> al final es\
<user1> 1 :to 100 :do [:i | Transcript show:'foo';cr ] pero no lo entiendo
<user1> el :i y el |
<rgrau`> (1 to:100 ) do: [:i| Transcript show: i;cr]
<user1> sin parentesis tambien va :)
<user1> pero bueno la idea es clara
<user1> hay un metodo to:do: que actua sobre enteros
<user1> que recibe un entero y una closure
<user1> y asi construyes un bucle
<rgrau`> sips
<user1> la sintaxis queda limpia y todo
<rgrau`> y te puedes montar tu 'sintax sugar'
<rgrau`> haciendo to:do: de Integer
<rgrau`> o do: de Range
<user1> yep, pero
<user1> que es el :i
<user1> ?
<rgrau`> es el parametro que recibe la closure
<rgrau`> (map (lambda (i) (print i)) (range 1 100))
<rgrau`> es la i
<user1> pero a que objeto se lo aplica? a ella misma?
<user1> :i es como
<user1> self :i
<user1> quiza?
<rgrau`> como?
<user1> la sintaxis normal es
<user1> objeto :attr
<user1> pero aqui solo aparece
<user1> :attr
<rgrau`> si, [] debe ser sintax sugar para BlockClosure new:'algo'
<rgrau`> me lo invento
<rgrau`> pero supongo que debe ser algo asi
<user1> ah, ok
<user1> bueno, creemos alguna clase :D
<rgrau`> oks
<rgrau`> systembrowser
<rgrau`> 1a columna, id abajo del todo
<rgrau`> click derecho, new category
<rgrau`> MiPrueba
<rgrau`> abajo nos sale un 'template' de codigo para crear clases
<rgrau`> ese texto lo evaluaremos ahi, pero no es distinto de un workspace
<rgrau`> osea, el texto, en un workspace haria lo mismo
<user1> click derecho donde?
<rgrau`> en el mismo listado
<user1> ah, en la columna
<user1> ok
<user3> Add Category?
<rgrau`> sips
<rgrau`> a la clase Object, le mandaremos el mensaje subclass:instanceVariableNames:classVariableNames:.....
<rgrau`> que es un metodo implementado en Objecto
<rgrau`> Object
<rgrau`> Object subclass: #Persona
<rgrau`> instanceVariableNames: 'dni telefono'
<rgrau`> classVariableNames: ''
<rgrau`> poolDictionaries: ''
<rgrau`> category: 'MiPrueba'
<user1> # es una sintaxis especial o convenio
<user1> ?
<rgrau`> es un simbolo
<user1> ok, #persona es lo que 'persona a lisp
<user1> ?
<rgrau`> sips
<user1> hecho :)
<rgrau`> seleccionar y evaluar
<rgrau`> do it
<rgrau`> alt-d
<rgrau`> clicas a persona
<rgrau`> y ves como lo has declarado
<rgrau`> si quieres anyadir otro attr, editas y vuelves a evaluar
<rgrau`> 'dni telefono edad'
<rgrau`> y do-it
<user1> rgrau`: category supongo que es como los espacios de nombres o asi, verdad?
<user1> perfecto, ya cree una instancia
<rgrau`> nope, no hay namespaces
<rgrau`> es una forma de organizar metodos
<rgrau`> pero es solo para visualizar
<user1> clases no?
<rgrau`> comor?
<user1> <rgrau`> es una forma de organizar metodos
<rgrau`> ah, sisis
<user3> Persona es la clase, no?
<rgrau`> perdona
<rgrau`> las 4 columnas son
<rgrau`> categorias,clases,protocolos,metodos
<user1> esta guay, ya me hago la idea,
<rgrau`> igualmente, no hay namespaces
<user1> si me dices la sintaxis para definir metodos ya puedo jugar un poco
<rgrau`> categoria y protocolo son para organiar
<rgrau`> si queremos subclasear Persona
<rgrau`> Persona subclass: #Menor
<rgrau`> instanceVariableNames: ''
<rgrau`> classVariableNames: ''
<rgrau`> poolDictionaries: ''
<rgrau`> category: 'MiPrueba'
<rgrau`> mandamos el mensaje a Persona en vez de Object
<user3> ajam
<user5> aqui hay una cosa interesante que ilustra el sistema de objetos
<user5> jej, eso
<rgrau`> :)
<user1> yep, de hecho tambien hay plantilla :)
<rgrau`> bien, ahora vamos a crear un metodo en Persona
<rgrau`> seleccionamos la 3a columna
<rgrau`> y se nos pone la plantilla esa
<rgrau`> currar
<rgrau`> Transcript show: 'estoy currando';cr
<rgrau`> y do-it
<rgrau`> y ahora desde un workspace
<rgrau`> |p|
<rgrau`> p := Persona new
<rgrau`> p currar
<rgrau`> seleccionar y doit
<user3> Donde pones currar?
<user3> En add category de la tercera columna?
<rgrau`> no, clicas en la 3a columna (para que la ventana de abajo cambie de 'scope')
<user1> unknown variable currar
<rgrau`> currar
<rgrau`> Transcript show: 'currar';cr
<rgrau`> talcual, primera linea 'currar'
<rgrau`> segunda linea: transcript.....
<user1> eso puse
<user1> do it
<user1> seleccionando todo, y me da eso
<rgrau`> en el system browser?
<user1> si, donde salia la plantilla
<rgrau`> y has eliminado la plantilla y has puesto esto?
<user5> recuerda "aceptar" los cambios
<user1> como?
<rgrau`> al hacer el doit te pedira tus iniciales
<user1> no llega a eso, me da el error antes
<rgrau`> aver, desde el principio, clicar en persona, clicar en 'no messages', clicar en la ventana de abajo
<rgrau`> meter el codigo
<rgrau`> ahhh
<rgrau`> vale
<rgrau`> alt-s
<user1> vale, con A-j si funciono
<user1> o ese tambine :)
<user1> el M-d es el que fallaba
<rgrau`> pq do-it, intenta evaluar, a saco
<rgrau`> 4+3 te lo evaluaria
<user1> perfecto, ya trabaja
<rgrau`> pero el m-s hace el accept en el scope correcto
<user5> en la ventana de texto, se cambia el borde de color cuando se ha modificado el code
<user5> aqui es "naranjita" :)
<user3> no me lo guarda :D
<rgrau`> sip. aki tb
<rgrau`> alt-s
<user3> ah, ahora esta en la cuarta columna
<rgrau`> yep. es donde debe estar
<rgrau`> lo guapo de el entorno controlao, es que para refactoring, el propio sistema controla referencias y tal
<rgrau`> la idea es que al crear la clase, has creado un objeto
<rgrau`> que ya esta 'vivo' en la imagen
<user1> yep, yo lo pille ya :)
<user1> bueno, como hago referencias a psible argumentos?
<user1> defino un
<user1> currar:n:
<user1> ?
<rgrau`> como?
<rgrau`> ah, si
<rgrau`> currar:horas
<rgrau`> 1 to:horas do:[self currar]
<rgrau`> sip, claro
<user1> horas hace referencia al valor no
<user1> ?
<rgrau`> sip
<user3> rgrau`: Otras implementaciones de smalltalk, distintas de pharo, no tienen porque tener necesariamente la misma gui, verdad?
<rgrau`> exacto
<user3> rgrau`: Y, en que se diferencia de squeak, lo has probado?
<rgrau`> si, pharo fue un fork de squeak
<rgrau`> bueno, pharo tiene la idea de ser algo production ready
<user5> viene a ser la version minimalista, profesional, y francesa de squeak :P
<rgrau`> squeak es mas de experimentacion
<rgrau`> user5++
<user1> (Persona new) currar horas:10
<user1> eso no deberia funcionar
<user1> ?
<rgrau`> Persona new currar:10
<rgrau`> o bien
<rgrau`> (Persona new) currar:10
<user1> error, 0 argumenos espera
<rgrau`> has definido currar con 1 parametro?
<rgrau`> o no la llegaste a definir
<user1> si claro
<rgrau`> ah, es verdad
<rgrau`> pera , k miro
<user5> ves currar: en la 4ta columna ?
<rgrau`> sisi
<user1> si, currar: justamente
<rgrau`> estan las 2
<user1> no currar:horas
<user1> pero no entiendo por que es currar:10
<rgrau`> ay
<user1> 1 :to 100 :do [ ... ]
<user3> (os sigo leyendo mañana, buenas noches, y gracias rgrau, siempre quise echarle un ojo a smalltalk)
<rgrau`> lo que dice el error es que dentro del do:[AKIVAELPARAMETRO]
<user5> buenas noches user3, un gusto
<rgrau`> do:[:AKIVAELPARAMETROQUENOQUIERESPARANADA| self currar]
<user3> Nos vemos en la próxima charla :)
<rgrau`> puedes hacer
<rgrau`> ciao user3
<rgrau`> currar:horas
<rgrau`> horas timesRepeat:[self currar]
<rgrau`> la cosa es que el bloque k le mandas a 'do', tiene que admitir un parametro
<rgrau`> Persona new currar:10
<user1> ahora si
<rgrau`> :)
<user1> pero sigo sin entender, a la hora de llamarlo
<user1> donde entra en juego el horas:
<user1> ?
<user4> wenas noches :)
<user1> como en 1 :to 100 do:
<user1> ahi el do: se escribe explicitamente
<rgrau`> si, pero en el codigo donde implementa el to:do: de alguna manera se tiene que referenciar a los valores que le estan pasando
<user5> ah creo que te pillo user1
<rgrau`> la implementacion de to:do: seguramente sera algo como
<rgrau`> to: anInteger do: aBlock
<user5> tu quieres escribir un metodo que acepte solo un arg, y que ese arg sea un keyword argument
<user1> user5: eso es
<rgrau`> Persona new 10? asi?
<user1> rgrau`: no
<user5> pero hemos escrito Persona#currar: foo horas: bar, que son dos argumentos, uno sin nombre explicito y otro nombrado
<rgrau`> no, era un solo argumento
<rgrau`> Persona>>currar:tantasHoras
<user5> lo que el quiere es un function(arg=anObject)
<rgrau`> lo llamas como Persona new currar:10
<user5> claro
<user1> ya pillo como va
<user5> user1 quiere poder escribir person currar horas: 10
<user5> donde horas seria el named arg del mensaje currar
<user5> no?
<rgrau`> aha, no entonces el mensaje se llamaria currarEnHoras:anInteger
<user1> no pero ya veo que no se puede
<user1> es que tenia en mente eso de que un metodo tiene nombre
<user1> pero el nombre son los argumentos en si
<user1> imposible :)
<user1> currar:10
<user1> y si quieres mas argumentos entonces si es posible
<user1> currar:10 :hasta 20
<user5> exacto
<user1> ya lo pille :)
<rgrau`> exacto
<rgrau`> al principio es un poco extranyo
<user1> na, es facil :)
<user5> es dificil decirlo solamente :D
<user1> rgrau`: al ejecutar la misma imagen se carga todo igual o
<user1> como puedo mantener varias imagenes diferentes?
<rgrau`> el rollo es chulo, no user1 ?
<user1> si si, esta guay :), aunque si el entorno fuese mas emacsero seria mejor :D
<rgrau`> cuando cierras la imagen, guardas
<rgrau`> :)
<rgrau`> y se queda todo talcual
<user5> que les parece si agregamos unas variables de instancia
<user1> rgrau`: ya pero
<user5> hola user4, btw
<user1> si quiero mantener 2 imagenes diferenteS?
<user1> 2 ramas
<rgrau`> en una misma imagen lo que esta cargao esta cargao, no hay tutia....
<rgrau`> tiene un sistema de control de versiones
<user5> user1: hay un "save as", pero el vcs es mejor creo
<user1> ah vale, que completo
<user5> y aun falta el debugger
<user5> y el unit testing
<user1> por mi hoy va bien :) que manyana tengo facultad
<rgrau`> el control de versiones va a nivel metodo
<rgrau`> es muy maleable supongo
<user5> me olvido que estan en +5
<rgrau`> jej
<rgrau`> bueno tio, pues nada
<rgrau`> user1: pues si te ha molao, yo contento
<rgrau`> otro dia debugger
<rgrau`> y luego la tuya de lisp
<user5> pues ha estado lindo, ty rgrau`
<user1> sep, voy a intentar escribir algo para
<user1> asentar lo aprendido
<user1> alguna sugerencia?
<user1> algo simple :)
<rgrau`> mmm.. nose
<user5> el ejemplo de pbe ?
<rgrau`> manyana lo miramos
<rgrau`> sip
<user1> muy bien, gracias rgrau`
<user1> hasta mañana a todos :)
<user5> hasta mañana user1
view raw st.txt hosted with ❤ by GitHub

martes, 17 de mayo de 2011

Ratpoison bindings without prefix key

My window manager of choice is ratpoison. It's a really minimalist tiling wm heavily inspired by gnu screen. As such, it has a prefix key (c-t by default) and most of the bindings mimic screen ones.

At work, I recently discovered that my boss uses ratpoison too (my project manager uses xmonad, great team, isn't it). He uses ratpoison with a different configuration scheme, banishing prefix key, and using definekey at toplevel for every command.

I'm not sure whether I like this configuration or not, but I'm going to try this for a few days, and see if it works ok or what. I've written some lines to enable toplevel bindings using the super key.

Avoiding c-t as a prefix key has its advantages, but now, 'super' key chords are all clobbered by ratpoison. We'll see how it works out.

#http://puntoblogspot.blogspot.com/2011/05/ratpoison-bindings-without-prefix-key.html
definekey top s-h focusleft
definekey top s-l focusright
definekey top s-k focusup
definekey top s-j focusdown
definekey top s-s vsplit
definekey top s-v hsplit
definekey top s-n nextscreen
definekey top s-p prevscreen
definekey top s-space next
definekey top s-u undo
definekey top s-o only
definekey top s-0 select 0
definekey top s-1 select 1
definekey top s-2 select 2
definekey top s-3 select 3
definekey top s-4 select 4
definekey top s-5 select 5
definekey top s-6 select 6
definekey top s-7 select 7
definekey top s-8 select 8
definekey top s-9 select 9
view raw .ratpoisonrc hosted with ❤ by GitHub

Smoke Driven Development

He pensado que podríamos usar git
Con un poco de scrum y si aprendo TDD lo tenemos hecho en dos semanas
Un par de branches, un par de slots
Dos cartas porahi, un coaching porallá
Y despues, fiesta de final de proyecto, cardhú, putas y farlopa. Pago yo.

-- Alguno que yo me sé --

martes, 10 de mayo de 2011

latex code listings in org-mode

I already talked about inserting code listings in latex some time ago. At @work
(in a ruby meaning, not a perl one), I try to write as much as I can
in org, and then export it to html, or pdf.

org-mode is fully capable of assisting you when writing code listings,
and it will export them with fancy syntax highlighting. When exporting
to html, it uses htmlize (emacs-goodies if you're in ubuntu). But when
exporting to LaTeX, things are not so straightforward. Of course,
there's extensive documentation, but sometimes, you just don't want to
read through hundreds of details. You just want something that
'WorksForMe (c)'.

(setq org-export-latex-listings t)
(add-to-list 'org-export-latex-packages-alist '("" "listings"))
(add-to-list 'org-export-latex-packages-alist '("" "color"))


I don't know if it's enough or there's another configuration related
to this sunken in my .emacs (now 609 lines long), but you know... It
WorksForMe.

viernes, 6 de mayo de 2011

Technologically impaired office



Ok, I've already spent too much time trying to write a doc in openoffice to acknowledge that most of general user-friendly apps are for total technologically impaired ducks. It's not that there are no shortcuts for everything, its much more simple than that.

Every single function has a button for it. You want to indent a paragraph, ok, there's a button for it, outdent, another button... The fscking problem is I'm not in the mood of looking through all the buttons of all toolbars until I find it. And guess what? Selecting a paragraph and pressing tab, just blows you paragaph away and adds a tab.

My Technologically impaired solution.
foreach @line {press(tab,↓,←)}

Popups are the root of all evil. Well, openoffice will nag you when the cursor is on a table, a numeration, or god knows what.

Nested enumerations with styles, another shitstorm.... Copypastable formatting, font, background highlight and all the unwanted persistency of a place-and-format. You will get signs from the past red bold letters that lived in the place you're editing 3 centuries ago.

For this and much more, I declare myself technologically impaired.

martes, 26 de abril de 2011

Perl, paths, local::lib and why I got stuck for a week

When writting ratfinder2, I started testing it in console, and when the main structure kind of worked (the plugin system is for Yet Another Post(tm) ), I wrote the gui stuff, and plugged alltogether. Everything worked ok when run from console. but if the program is executed directly through a ratpoison binding, the script didn't work.

After some debugging time, and nothing seeming to make sense, trying && failing while(1..Inf);... the solution is here.

The thing is that when executing the perl script directly, .zshrc doesn't get executed, so the path isn't added. Be able to run the script we can use 'use lib "/home/rgrau/perl5/lib/perl5";', or otherwise call the script with the -I flag setting the appropiate path.

I suppose if you bind an icon on gnome/kde/windows to a perl program, you should be aware of that, and bind the icon to the appropiate command.

so now, my ratpoisonrc line is like


bind j exec perl -I/home/kidd/perl5/lib/perl5 ~/bin/rat-finder.pl
bind C-j exec perl -I/home/kidd/perl5/lib/perl5 ~/bin/rat-finder.pl


I know it seems obvious now, that you should tell your perl where the modules are, but once you forget about local::lib.... It can't be unforgotten :). The opposite of THIS

martes, 19 de abril de 2011

Open2 for dummies

Some days ago I started rewriting ratfinder, and I'm trying to make it cleaner, smarter, more extensible, and (why not) have more fun programming it.

The language of choice is still Perl5, because I'd like to keep in touch with the language, and keep learning new tools and libs for it. Ruby is ok, but honestly, if we're not talking about god's purity (those two old languages), Perl is my favourite bitch.

The first design decision was to make it extensible via a plugin system, where you provide a couple of methods, consume a role (Moose, yeah), and ratfinder2 will do 'the right thing'(tm).

I'll talk about the plugin system in another post, but today, I had a simpler problem (at least at first sight).

One of the multiple ways to spawn new processes in perl, is using the super-duper-overpowered-open primitive, with a pipe attached into the name of the process. I still remember One of Casiano's example on it. Quite mindblowing when you first see it.

But what happens when you want not only INput OR OUTput pipes but INput AND OUTput pipes for a process?

Hey, it's Perl, you know man, TIMTOWTDI. IPC::Run, Capture::Tiny, IPC::Cmd.... but the standard way is, for the moment, IPC::Open2.

It's usage may be trivial for you, but for me, the doc is a bit behind the times, as it uses GLOBS for handles, and the examples didn't clarify much for me.

The key concept for me is knowing that the whole thing works when your write pipe is closed (at least it seems so), so if you can't make your host process close it, you should close it by yourself.

Here's the part of relevant code in my Dmenu.pm

package Ratfinder::GUI::Dmenu;
use feature ':5.10';
use Moose;
use IPC::Open2;
use IO::Handle;
extends 'Ratfinder::GUI';
sub prompt {
my ($self, $text, @completions) = @_ ;
my ($wrt, $rdr) = (IO::Handle->new, IO::Handle->new );
my $pid = open2($rdr, $wrt, 'dmenu -i' );
print $wrt join("\n",@completions);
$wrt->close;
my $got = <$rdr>;
wait;
$got;
}
1;
view raw Dmenu.pm hosted with ❤ by GitHub


As usual, everything is public, undocumented, buggy, and it's on github.

lunes, 4 de abril de 2011

What you can't see CAN hurt you (or, at least, annoy you)



Most of the times, and programming in sane (cough, cough)
programming languages, things like whitespaces, tabs and newlines
won't do you much harm. they work as separators for tokens (unless
in a string).

But that doesn't mean that you can't get trapped into some gotchas
related to whitespaces or newlines. One example everyone has dealt
is lineFeed vs carryReturns vs CRLF.

There's a funny article from fxn on O'Reilly site talking about
the secrets and gotchas of newlines.


As a long time vim user, and nearly a year of using emacs (with
different intesities), I care a lot about my editor features, and
one feature that's really useful is the 'select paragraph'. Both
emacs and vim can do this out of the box, but there are some
problems when you aren't careful enough and leave apparently blank
lines that are full of spaces, tabs or any invisible characters.

In vim, you can delete all trailing whitespaces with a simple
regex. Of course, you can create a command to do it for you, or even
map some keybinding to execute %s/\s\+$// , but I'm ok with typing 10 chars for it.

In emacs, of course there's a command for deleting trailing whitespaces, and, guess what?
it's called delete-trailing-whitespaces :) .

If you want emacs to show trailing whitespaces, there's a buffer-local variable called
show-trailing-whitespace that you can set to true. Here's the official emacs doc

Emacs has a command called 'whitespace-cleanup' that bundles some sane (configurable) rules to clean most annoyances related to whitespaces.

viernes, 1 de abril de 2011

Modern Perl Toolchain, dip your toe

Yesterday, we had another Bcn PerlMongers meeting, and AlexM showed us some nifty tools he's using in a project he's into.



Basically these are what in the perlsphere is called Modern Perl Toolchain.



Forget about cpan asking tons of questions, forget about only one
location for modules.


With the help of:




And some plugins for dzilla, you get isolated perl instalations, with
their own modules (@INC), and a trully easy maintenance of
Boilerplate. In fact, it's as easy as it can get, because, you don't
have to do any dedicated maintenance for them.


I had tried some of the old ways to package apps, and so, and when I
saw the power of these 3 modules (I had already used cpanm, but..), I
felt we got an autoshaving yak.


Here are the slides that AlexM kindly uploaded today.


During the talk, some modules arouse to the conversation, and I
took a look at some of them:



similar to Casiano's Remote::Use, but probably easier in its usage. a big win.


That's the killer one for me. It hooks on die signal, and spawns a
REPL and you have then access to the whole environment. Great great great.


If you want to set 'breakpoints' you can hook warns instead of just exceptions.


And another cool feature is that you use it just enabling it from the commandline


perl -MCarp::REPL

martes, 22 de marzo de 2011

Managing the unmanageable with git

After 2 months using git regularly, there are a couple of things that I'd like to comment here, just for further adding on other posts.

Mostly, for me there's a first blocker that is understanding how the global thing works. To solve this, I can recommend git from the bottom up. a great introduction to git written quite differently from most other docs that want to explain the same. Understanding the low level stuff helps you getting intuition, and IMHO it's essential to get this kind of intuition when using such holistic systems.

Most tutorials give you the essential syntactic information that you can get from man (btw, man git-whatever will give you lots of info), but for me, knowing the workflow and how-to think gittish (or thinkgit if you prefer) is what bothered me most of the time.

You probably have heard about nvie's git workflow. I haven't tried it yet, and at work we use a simpler workflow based on a remote master branch, two local branches (master,working) and quite centralized flow.

Not being a git power user (I'd say I'm just scratching the surface) I'm going to write a couple of posts that are what I'd have needed when I started with it seriously.


Checkout - what happens when you checkout
Clean - oops, I think I messed something
Stash - Smashing the stash for fun and profit
Rebase - commit -am 'fdsda'
Bisect - It's always been that way NOT!


If you have suggestions or something to add, I hope you will comment. Remember, I'm learning as I write these posts, so you can and MUST collaborate!

lunes, 7 de marzo de 2011

Perl Higher Order Functions

I've been chit-chatting with a friend who's learning Perl5, and has written some little apps for his own needs. While reviewing his code (not that I'm a programming guru, but I help with what I can), I talked about Higher order functions, and we ended writting some throwaway code to explain the idea.

To clarify the concepts, I wrote some trivial scheme functions-as-data munging in scheme, and translated them to Perl.

What surprised me, was the "wow!" comments about concepts that aren't perl unique features, but general higher order procedures. Certainly, Java and C++ are 'a bit' behind Perl, Ruby, or Lisp, but it's fun to remember how mind blowing are these concepts to newcomers. I discover mind-blowing concepts quite frequently too.

We had a good afternoon, reviewing code, Quines, concurrency, talking about GEB (The book I'd take to a desert island along with SICP)...

Here's part of the code we've written (as a reminder). Nothing useful, but tiny proof of concept of HOP. Ah, btw, I recommened him to read chromatic's Modern Perl book. I recomend it to all of you in the Perlsphere. Great book.

#!/usr/bin/perl
use strict;
use warnings;
use feature ':5.10';
sub idem { shift }
sub plus_n {
my $fun = shift;
my $n = shift;
return sub {
$fun->(shift) + $n;
}
}
say idem(3);
my $anon = sub { shift };
say $anon->(4);
my @arr;
foreach my $i (1..10) {
push @arr, plus_n($anon,$i);
}
foreach my $fun (@arr) {
say $fun->(1);
}
# vim: set tabstop=4 shiftwidth=4 foldmethod=marker : ###}}}
view raw HOPtest.pl hosted with ❤ by GitHub

domingo, 6 de marzo de 2011

Window navigation on Emacs

Last week I was talking about some emacs features with a coworker (while talking about General User Interfaces, pros and cons of WIMP), and ended with the doubt whether there is a way for easier window navigation on Emacs, or c-x o is the only way to go.

I talked about one of the greatest aid to frame/window navigation of screen and ratpoison, that is window numbering, and being able to switch to random windows instead of just sequentially.

Well, today I spent some time thinking about possible solutions, and searching for already implemented modes.

Guess what? There are a couple of ways already implemented (in default emacs, or as an extra downloadable package).

Windmove comes bundled with emacs since 21-dot-something, and in fact is what vimpulse uses for the c-w [hjkl] emulation.
(windmove-default-keybindings) ; enable shift-arrow
Expanding the concept further, there's also FrameMove, that integrates seamlessly with windmove. Here's a little extra info about it.

I found a couple of more esoteric plugins to navigate windows, but haven't tried them.
http://blog.lathi.net/articles/2007/11/07/jumping-to-specific-windows-in-emacs explains how to jump to windows by title. I suppose like ido-mode or anything-buffers.

There's also https://github.com/dimitri/switch-window , that seems to bring ratpoison's numbering of frames to emacs' windows. Nice idea. Here follows a screenshot of switch-window from it's homepage.

lunes, 28 de febrero de 2011

Programmer problem solving sequence

2010 developer’s problem solving sequence:

  1. Google
  2. Coworkers
  3. StackOverflow
  4. RTFM
  5. Think

It's funny because it's true.

Via HN -> JCook -> Philippe Leybaert

lunes, 21 de febrero de 2011

run interactive applications inside emacs

While implementing a more decent repl for HAScheme, I stumbled upon a nifty emacs feature: comint.

To run an interactive shell, get history for free, and completion (at least hippie-expand if you teach your emacs to use it), you just have to use make-comint.


(defun run-has ()
(interactive)
(make-comint "has" "/path/to/hascheme/script/lis.pl" nil "/path/to/hascheme/script/builtins.scm"))


the last parameter is the argv, you can fill it with whatever you want. In my case, the scheme file with some builtins.

On the hascheme side, I've been experimenting with tail call optimitzation, an improved repl with multiline support and with some cool debugging features. You'll know shortly about them if you follow this little blog of mine.

Well, and here's a screenshot of the comint buffer on hascheme. note the completion thing on the minibuffer.

martes, 8 de febrero de 2011

(let ((there be)) lisp)

I keep having lots of fun with hascheme. In the last couple of
days, I implemented quite a few things. Mostly they are syntax
sugar for things you could already do in HAS, or useful procedures
needed for my basic interpreter testing.


  • Perl side

    • (define (fun args) body) is now accepted as an alternative way
      to declare procedures.

    • (let) implemented. These bindings for local vars are just sintactic sugar for
      what you'd write in perl:
      sub { my $a=shift; … }->(initialval)


  • Scheme side
    Reread the 'Why functional programming matters' paper, and implemented:

    • make-counter, foldr

    • append, sum-list, length, map . All are specific cases of the previous


Reading chapter 4 of our MIT beloved book, I saw the next step, making a lazy
interpreter from this Half Assed one.

Ah, the repo

lunes, 7 de febrero de 2011

Put more vim into your emacs


I'm a vim editing model fan, but emacs is slowly crawling into my
life. emacs had viper (vi emulator) for ages, but it falls short if
you're a vim power user. Vi is not Vim.



For some time there's been vimpulse package that tried to narrow the
difference, adding Visual mode, and some other goodies. Recently,
vimpulse got reactivated, and now, we get text objects, and many
other features from our beloved text editor.



You can even use map, imap, vmap and the like;



the first thing I tried was mapping jk to esc, but the tip in the
vimpulse wiki didn't work. I managed to make it work with this line
in my .emacs file.



(vimpulse-imap "jk" 'viper-exit-insert-state)



Now, there's no need to reach the far escape key.