Um2010

Embed Size (px)

Citation preview

Spot Your White Caml

Make Yourself Happy
in OCaml Projects

BTW

J. Furuse aka CamlSpotter

15 years of OCaml programming3 years of Functional Quants

Scenario

You have jumped into an OCaml Project.

Congrats : Your Choice was Correct!

OCaml is a good to get your work done:

Type-safe

Enough Stable

Reasonably fast

Very simple

Readable

Scalable

Strong abstraction

Multi-paradigm

Typical Day 1 : Welcome!

Nice and Kind Colleagues

New Cool Office

Good Machine

Even A Welcome Party!

Typical Day 2 : Real Job Starts

Typical Day 2 : Real Job Starts

Overwhelmed

type 'a desc = { position : Postion.t; value : 'a }

let rec typecheck env = function Exp_int n

open Utils open Sourceloc open Spot

module Kind = struct include Kind let to_string = function Value -> "Value"

let escaped pred s = let b = Buffer.create (String.length s) in String.iter (fun c if pred c then Buffer.add_char b '\\';

module Make (M : Basic) : S with type 'a monad = 'a M.t = struct let bind = M.bind

type error = E2BIG | EACCES | EAGAIN | EBADF

let cflag_of_int = function | 0x0001 -> `CASELESS | 0x0002 -> `MULTILINE | 0x0004 -> `DOTALL | 0x0008 -> `EXTENDED

class ['a] gobject_signals obj = object val obj : 'a obj = obj val after = false method after = {< after = true >} method private connect : 'b. ('a,'b) GtkSignal.t -> callback:'b -> _ =

Typical Day 100

Typical Day 100

Still being Overwhelmed...

type 'a desc = { position : Postion.t; value : 'a }

let rec typecheck env = function Exp_int n

open Utils open Sourceloc open Spot

module Kind = struct include Kind let to_string = function Value -> "Value"

let escaped pred s = let b = Buffer.create (String.length s) in String.iter (fun c if pred c then Buffer.add_char b '\\';

module Make (M : Basic) : S with type 'a monad = 'a M.t = struct let bind = M.bind

type error = E2BIG | EACCES | EAGAIN | EBADF

let cflag_of_int = function | 0x0001 -> `CASELESS | 0x0002 -> `MULTILINE | 0x0004 -> `DOTALL | 0x0008 -> `EXTENDED

class ['a] gobject_signals obj = object val obj : 'a obj = obj val after = false method after = {< after = true >} method private connect : 'b. ('a,'b) GtkSignal.t -> callback:'b -> _ =

Why

You feel yourself Dumb ?

Seniors look Smarter than you ?

You

Senior

Answer : Curves

Learning vs Code Growth

Time

LoC

Seniors

Answer : Curves

Learning vs Code Growth

Time

LoC

Eternal Rookies

Seniors

Improve Your Learning Curve

How toRead the Code

Write Good Code

Ask Questions

Minimize Reading Effort

Read .mli First

Read interfaces (=.mli) first

Skip implementations (=.ml) if possible

Write Good .mli

Good for Yourself and the OthersHide implementation details

Show the things the users should care

With GOOD and SHORT comments

Let TYPES tell details of functions

ocamlc -i gives a good start point

Do NOT Guess .mli

No GOOD .mli found ?Do NOT waste time to guess interfaces

Ask the Authors write them

Write them,or I get Home.Not something
automatically
created.

Do NOT Ask Silly Questions

In OJT, your job is asking QUESTIONS, wisely.

Where is it?

In foo/bar.ml Where is this?In bar/boo.mli What is that?Uh, oh...

Ask Good Questions

Read code to get HOW

Then Ask WHY, which the Code does NOT tell you

Why this data type is
designed like this? Some combinations never
appear in the algorithm.
It could be simpler.

Oh, this new guy is Strong...

Still NOT ENOUGH

How to Read, Ask, and Write are important.

But NOT the most Critical!

Where is Your White ?

80% of Your Energy is for Searching

Where is the definition of this and that ?What the type of this ?

Syntax Hilighting

It improves Local Vicinity of your Code.caml-mode.el (with OCaml)

tuareg-mode.el (1.45.6-2 / 1.46.2 / (2.0.1))

{syntax,ftplugin,indent}/ocaml.vim (2010 Aug 07)

Manual Search

It NEVER Scales. You are warned.Names are definedabove in the file

in Pervasives

in file system (include path)

in opened modules

, or in aliased modules

Grep

OCaml syntax Verbosity helps, but not always...

grep iter *.mlgrep 'let iter' *.mlgrep -n '\(let\|let rec\|and\) iter' *.mlfind .. -type f -name '*.ml'
| xargs grep -n '\(let\|let rec\|and\) iter'

Tags

Tags do NOT help you lot in OCamlJust a clever Grep.Otags for OCaml 3.11.1 (http://askra.de/otags/)

Others (OCamlOTags, ocamlglobaltags, ...)

IGNORE your Seniors

I am always OK with Grep

Manual Search is pain but also Educational

Don't worry. You will be soon Used to the code

Your situation is Worse than them.You need something Different.

Use the Compiler Directed Tools

Compiler knows HOW things are coded.

Source

Obj

Useful Info

Types of Locals as Documents

.annot by ocamlc -annotTypes of local values
and sub-expressions

caml-types.el (caml-mode)

ocaml.vim

.annot

Search by Names

CmiGrep.cmi search (= only for exported)

cmigrep -v iter '*'

cmigrep -I .. -v iter '*'

A bit tricky...cmigrep -v 'iter' '*.*'

.cmi

Search by Type Algebra

OCamlBrowser / OCaml API SearchGraphical / Web search of .cmi

Good for Writing

OK for Reading

.cmi

Search by Position

I want to know about .... THIS!

ThisThis

It was impossible;
OCaml compiler threw positions away.

OCamlSpotter

Specialized to find your WHITE.spot / .spit filesDef locations (including locals)

Use locations

Module abstractions

Types

Compilation flags

.spot, .spit

Extended ocamlc / ocamlopt -annot

ocamlc -annot creates .spot files.spot for .ml

.spit for .mli

.spot, .spit

ocamlspot CLI

% ocamlspot :Type:
XType:
Use: ,
Tree: :
In_module:
Spot: ::

OCamlSpotter Editor Integration

Wrapper for OCamlSpotter CLIocamlspot.el for Emacs

ocamlspot.vim for Vim (just done. Plz extend it.)

OCamlSpotter in Compiler

ProsDump during Type Checking

Compiler version dependent

No information gathering overhead

Just add -annot

OCamlSpotter in Compiler

ConsYou need the Patch

Patched compiler may be Buggy.Patched compiler produces the same objs for ocamlc

ocamlspot can be used for .spot creation tool

Use OCamlSpotter. Be Creative.

Searching = x3 Creative

Before

After

Use OCamlSpotter. Be Creative.

Trust me. It's worth Patching.Good even for One Man Army

No equivalentOCamlWizard (Stopped at 3.10.2)

OcamlSpotter is available for 3.12.0 :http://jun.furuse.info/hacks/ocamlspotter

hg clone http://hg.ocamlcore.org/cgi-bin/hgwebdir.cgi/ocamlspotter/ocamlspotter/

Technical Details of OCamlSpotter

Less interesting things.

Spot is a program

It is not a simple
name-position record.

Late binding

Compute all at compile time is costy & impos.

Module as name-position record

Module alias as let

Functor as function

Recursion for Recursive modules

Laziness for efficiency

Spot is a program

ocamlspot --dump-top

Late Binding

a.mla.mlib.ml

a.cmoa.cmi

b.cmo

Late Binding

a.mla.mlib.ml

a.cmoa.cmi

b.cmo

a.spota.spit

b.spot

New dependency
between .spots,which is not known
to the build system.

OCamlSpotter API

Future PossibilitiesFinding Where USED ? not Where defined ?

Code refactoring

Jump to Document instead of Definition

Auto-recompilation independent from build sys

Co-op with other tools (.spot knows -I flags)

Other Tools for OCaml Reading

Cameleon2 : Nice GUI tools.... But, GUI!?!?!

OCamlDoc depgraphs (in OCaml)

Oug

Some Eclipse plug-ins (Useful???)

OCamlSpotter is Proven

It earns 1$ for each search!

When is it integrated into the official OCaml ?

I cannot live without it!!

And Now...

I jumped into a Haskell Project. Same story begins.

Make Yourself Happy
in OCaml Projects

Column 1

Searching80

More Creative20

Column 1

Searching80

More Creative20

Column 1

Searching40

Others60