Arquiteto de Software
Cientista de Dados
Sobre coisas que podem entrar em main stream (eu espero), de outra linguagem "Lisp-like":
Racket
It's 2002, and programming languages have almost caught up with 1958.
Paul Graham
"Revenge of the Nerds"
Paul Graham
with-bindings? Globais? Singleton? Ler um arquivo de config no meio do código?
*Avdi Grimm - Exceptional Ruby
#lang racket
(define number-of-threads
(make-parameter 2))
(define (work)
;work hard!
(displayln (number-of-threads)))
(work)
(parameterize ([number-of-threads 42])
(work))
(work)
Linguagens já tem "thread local".
Uso desencorajado :(
Configs são uma zona.
Racket parameters parecem:
- Fáceis
- Úteis
- Realmente fáceis
Parameters...
open/finally/close? ensure? using? with-open?
(define (do-work a-function) (define cust (make-custodian)) ... (parameterize ([current-custodian cust]) (dynamic-wind (λ () ... inicializa (λ () ... faz algo/abre coisas (λ () (custodian-shutdown-all cust))))
File
Thread
Socket
?
Cust 1
Cust 2
Cust 3
Libera vários recursos em uma única chamada.
Racket custodians parecem:
- Seguro
- Fáceis
- Ainda não muito polidos
("dynamic-wind")
Custodians...
(define (hello b) (let ([a "Hello,"] [c "!"]) (format "~a ~a~a" a b c)))
(define-syntax-rule (given (bind expr) ...) (begin (define bind expr) ...))
(define (hello b) (given [a "Hello, "] [c !]) (format "~a ~a~a" a b c))
vamos exagerar um pouco :)
(define-syntax (given stx) (syntax-parse stx #:literals (=) [(_ bind = expr) #'(define bind expr)] [(_ bind = expr rest ...) #'(begin (define bind expr) (given rest ...))]))
(define (hello b) (given a = "Why" c = "???") (format "~a ~a~a" a b c))
Racket style
#lang racket (require threading) (~>> '(100 200 300 400) (map add1) (take _ 2)) (~> '(100 200 300 400) (map add1 _) (take 2))
Macros são metaprogramação.
Racket macros parecem:
- Poderosas
- Simples Limpas
Rust já tem "Pattern-based macros".
Macros...
>_<
(regexp-match #px"\\d+" "123"
^_^
(regexp-match /\d+/ "123")
Linguagens não costumam deixar você definir literais.
Regexp, DateTime, Money, SQL, métricas, etc...
Racket reader macros são:
- Poderosas
- O jeito "certo"®
- Ainda falta polimento
Reader macros
Arquivo = módulo (masomenos)
Cada módulo ter em interface
O módulo é o que ele vê!
Cada módulo
é uma linguagem
Module
Module
hate-define.rkt
#lang racket
(provide (except-out (all-from-out racket) define)
(rename-out (define def)))
hate-define-use.rkt #lang s-exp "hate-define.rkt" (defineadd2 (λ (x) (+ x 2))) (def add2 (λ (x) (+ x 2)))
Deixa eu mostrar um truque bacanudo :)
Em Racket, toda aplicação de função usa #%app por baixo dos panos...
(add1 10)
...
(%#app add1 10)
Posso redefinir #%app com módulos
#lang racket (provide (except-out (all-from-out racket) #%app) (rename-out [my-app #%app])) (define-syntax-rule (my-app proc args ...) (begin (displayln proc) (#%app proc args ...)))
(add1 10) ... (begin (displayln add1) (%#app add1 10))
(add1 10)
...
(%#app add1 10)
Namespaces, import, requires são meio bagunçados.
Cada linguagem faz de um jeito.
Racket modules parecem:
- Poderosos
- Simples
Modules!
Phase Levels
Places (parallel processing)
Continuations (nothing new :p)
Contracts (Eiffel-like)
FFI
Racket não tem multimétodos, isso é meio estranho no começo (tem generics)
As coleções são meio... meh... use: data/collections
Para aprender a criar linguagens:
Degugging:
racket -l errortrace -t <prog>
Ronie Uliana
ronie@vagas.com
@ronie
medium.com/@ronie
github.com/ruliana