... until the collector arrives ...

This "blog" is really just a scratchpad of mine. There is not much of general interest here. Most of the content is scribbled down "live" as I discover things I want to remember. I rarely go back to correct mistakes in older entries. You have been warned :)

2008-01-31

Vital and Pivotal

Vital is a Haskell implementation that takes a document-centered approach, much like a Mathematica notebook.  Its successor, Pivotal, is a Haskell re-implementation of the Java original.  Pivotal is only in the early stages.  Both feel like incomplete implementations, but Vital in particular seems suitable for sandbox-style exploration of Haskell.

Implications of Non-Strict Functions

Here is a great little Haskell snippet that will wrench you out of imperative thinking:

notimperative x = (a,b,c,d) where
  (a,b) = incr x c
  (c,d) = incr d a
  incr i j = (i+1,j+1)

The result of evaluating notimperative 1 is (2,5,4,3).

A pithier, but more obvious, version is:

notimperative2 x = (a,b) where
  (a,b) = (b+1,x)

2008-01-29

Ivy

Ivy is the Ant group's answer to Maven.  It provides dependency management that is tightly integrated with Ant.


2008-01-26

Sandboxie

Sandboxie is a Windows virtualization application that allows you to run arbitrary programs within an isolated sandbox.  It prevents applications from making permanent changes to the true file system and registry.  Apart from the security service that it may provide, it allows you to test software installers without making any permanent changes to your system.


2008-01-22

Polyglot Blog

Luis Diego Fallas is a programming polyglot who keeps a blog, Exploring Beautiful Languages.


MIT Open CourseWare

MIT has an excellent site with lecture notes and other material available on their Open CourseWare site.


2008-01-21

XSTM

XSTM is an open source library that implements software transactional memory.

Speaking of STM, Simon Peyton Jones has written a great paper about implementing STM in Haskell, Beautiful concurrency.


2008-01-18

XSLT Root Node Problem

I am stumped by what appears to be a bug in both the IE7 and Saxon6.5.5 - which leads to wonder if it is not a bug at all but rather my misunderstanding of the way things work.  I tried to write a recursive XSLT template that worked its way up the element hierarchy, recursing until the node set '..' was empty.  To my surprise, an endless recursion occurred.  If I run Saxon in the debugger, I get the following expected results when the context has '.' bound to the top-most XML element:

local-name(.) -> test-checklist (my outermost element name)
local-name(*[1]) -> category (the element name of the first child element)
count(. | /) -> 2 (this node is not the root)
count(.. | /) -> 1 (the parent node is the root)
count(/..) -> 0 (the root has no parent)

However, if I then try <xsl:apply-templates select=".."/>, '.' is still bound to the document's outermost element (test-checklist in this case).

I tried the Xalan and .NET 1.0 transformers as well.  Everyone agrees - an endless loop occurs.  I don't understand this, and I've scoured both the XSLT and XPath specifications to find an explanation (without success).  As a workaround, I changed the termination test to 2 = count(.. | /).

Update:  I found it.  My template was matching '*'.  '*' does not match '/'.  Thus, once my code recursed up to the root, the default template rule for '*|/' kicked in.  The default rule invokes apply-templates on the context node's children.  Thus, execution would just rattle around on the top-most element.  Subtle.


2008-01-17

Prefuse

Prefuse is a nifty-looking data visualization library for Java (and soon Flash).


2008-01-11

IE7 vs Line Breaks

In IE7 (and maybe other versions of IE), line breaks are represented as carriage returns (only).  You will see this, for example, if you use DOM to extract text from a PRE element.


2008-01-09

Scala Partial Functions

In Scala, a block that contains a series of case expressions defines a partial function, thus:

val x: PartialFunction[Any,Int] = {case x: String => 1 case _: Any => 2}

Note that the type of x in the example must be specified because the input parameter to the partial function cannot be inferred.  This would not be necessary in circumstances where there is enough information to infer the type, e.g.

def doit(f: PartialFunction[Any, Int]) = f("hi")

doit({case x: String => 1 case _: Any => 2})

SQL Server Query Analyzer vs 'GO'

Be aware that Query Analyzer (and presumably OSQL) takes any line consisting solely of the word 'GO' as a batch terminator -- even if that word appears within a block comment.

SQL Server System-Generated Names

On SQL Server, the following query will list all SQL elements that have system-generated names (e.g. indexes, constraints):

select tab.name "table", obj.type "type", obj.name "name"
from (
  select null "type", null "name", null "tableId" where 1=0
  union select 'index', name, id from sysindexes where name not like '_WA_SYS%'
  union select 'primary key', name, parent_obj from sysobjects where xtype='PK'
  union select 'foreign key', name, parent_obj from sysobjects where xtype='F'
  union select 'check constraint', name, parent_obj from sysobjects where xtype='C'
  union select 'unique constraint', name, parent_obj from sysobjects where xtype='UQ'
  union select 'default constraint', name, parent_obj from sysobjects where xtype='D'
) obj
inner join sysobjects tab on (tab.id=obj.tableId)
where objectproperty(obj.tableId, 'isMsShipped')=0
and obj.name like '%\_\_%' escape '\'
order by tab.name, obj.type, obj.name

2008-01-08

Retrieving SQL Server Objects by Structure

Indexes

On SQL Server, the following SQL statement will determine the name of an index given its key columns:

select idx.name
from sysobjects tab
inner join sysindexes idx on (idx.id=tab.id and idx.name not like ''_WA_SYS%'')
where 0=(
  select sum(1)-sum(case when col.name=need.name then 1 else 0 end)
  from sysindexkeys ikey
  inner join syscolumns col on (col.id=ikey.id and col.colid=ikey.colid and ikey.id=idx.id and ikey.indid=idx.indid)
  full join (
    select null keyno, null name where 1=2
    union select 1, 'lineItemId'
    union select 2, 'projectId'
  ) need on (need.keyno=ikey.keyno)
)
and tab.name='lineItem'

Note the cryptic _WA_SYS reference.  SQL Server creates indexes that start with that prefix to support statistics operations.  It can happen in practice that there are two indexes on the same column set: one user index plus one system index.  We need to ignore the latter.

Primary Keys

In a similar vein, here is a statement to identify a primary key structurally (note that column order is not relevant):

select pk.name
from sysobjects tab
inner join sysobjects pk on (pk.parent_obj=tab.id and pk.xtype='PK')
where 0=(
  select sum(1)-sum(case when col.name=need.name then 1 else 0 end)
  from sysindexes idx
  inner join sysindexkeys ikey on (ikey.id=idx.id and ikey.indid=idx.indid)
  inner join syscolumns col on (ikey.id=col.id and col.colid=ikey.colid)
  full join (
    select null name where 1=2
    union select 'chartId'
    union select 'rowId'
    union select 'chartIndex'
  ) need on (need.name=col.name)
  where idx.name=pk.name
)
and tab.name='tbCustomChartDataSet'

Foreign Keys

To find a foreign key:

select fk.name
from sysobjects tab
inner join sysobjects fk on (fk.parent_obj=tab.id and fk.xtype='F')
where 0=(
  select sum(1)-sum(case when col.name=need.name and rcol.name=need.rname then 1 else 0 end)
  from sysforeignkeys con
  inner join sysobjects rtab on (rtab.id=con.rkeyid)
  inner join syscolumns col on (col.id=con.fkeyid and col.colid=con.fkey)
  inner join syscolumns rcol on (rcol.id=con.rkeyid and rcol.colid=con.rkey)
  full join (
    select null name, null rname where 1=2
    union select 'projectId', 'projectId'
    union select 'projectStageId', 'projectStageId'
  ) need on (need.name=col.name and need.rname=rcol.name)
  where con.constid=fk.id
  and rtab.name='tbProjectStageXref'
)
and tab.name='lineItem'

Column Constraints

To find a column constraint of some type (a 'check' constraint in the example):

select def.name from sysobjects def
inner join sysobjects tab on (tab.id=def.parent_obj)
inner join sysconstraints con on (con.id=tab.id and constid=def.id)
inner join syscolumns col on (col.id=tab.id and col.colid=con.colid)
where def.xtype='C'
and tab.name='unitConvVolume'
and col.name='qty_2'

Unique Constraints

To find a column constraint of some type (a 'check' constraint in the example):

select idx.name
from sysobjects tab
inner join sysobjects con on (con.parent_obj=tab.id)
inner join sysindexes idx on (idx.name=con.name)
where 0=(
  select sum(1)-sum(case when col.name=need.name then 1 else 0 end)
  from sysindexkeys ikey
  inner join syscolumns col on (col.id=ikey.id and col.colid=ikey.colid and ikey.id=idx.id and ikey.indid=idx.indid)
  full join (
    select null keyno, null name where 1=2
    union select 1, 'budgetId'
    union select 2, 'afeName'
  ) need on (need.keyno=ikey.keyno)
)
and tab.name='tbAfe'

Script Generation

Even more exciting, here is an SQL statement that generates an SQL script that can be run in another database to rename all indexes to match the names used in the first database (only indexes on user tables and that are not associated with a constraint or 'text' column are considered).

select text from (

select null tab, null idx, null seq, null text where 1=0

union select tab.name
, idx.name
, blk.seq
, replace(replace(blk.text, '$TABLE$', tab.name), '$INDEX$', idx.name) text
from sysindexes idx
inner join sysobjects tab on (tab.id=idx.id)
cross join (
  select null seq, null text where 1=0
  union select 1,     'declare @idx_name sysname'
  union select 2,     'select @idx_name=tab.name+''.''+idx.name '
  union select 3,     'from sysobjects tab '
  union select 4,     'inner join sysindexes idx on (idx.id=tab.id and idx.name not like ''_WA_SYS%'') '
  union select 5,     'where 0=( '
  union select 6,     '  select sum(1)-sum(case when col.name=need.name then 1 else 0 end) '
  union select 7,     '  from sysindexkeys ikey '
  union select 8,     '  inner join syscolumns col on (col.id=ikey.id and col.colid=ikey.colid and ikey.id=idx.id and ikey.indid=idx.indid) '
  union select 9,     '  full join ( '
  union select 10,    '    select null keyno, null name where 1=2 '
  /* 1000-9999 reserved for key column names */
  union select 10000, '  ) need on (need.keyno=ikey.keyno) '
  union select 10001, ') '
  union select 10002, 'and tab.name=''$TABLE$'' '
  union select 10003, 'exec sp_rename @idx_name, ''$INDEX$'', ''INDEX'''
  union select 10004, 'go'
  union select 10005, ''
) blk
where tab.xtype='U'
and idx.indid<>255
and idx.name not like '_WA_SYS%'
and not exists (select 1 from sysobjects where name=idx.name)

union select tab.name
, idx.name
, 1000+ikey.keyno
, '    union select '+cast(ikey.keyno as varchar)+', '''+col.name+''''
from sysindexes idx
inner join sysobjects tab on (tab.id=idx.id)
inner join sysindexkeys ikey on (ikey.id=idx.id and ikey.indid=idx.indid)
inner join syscolumns col on (col.id=idx.id and col.colid=ikey.colid)
where tab.xtype='U'
and idx.indid<>255
and idx.name not like '_WA_SYS%'
and not exists (select 1 from sysobjects where name=idx.name)

) data

order by tab, idx, seq

2008-01-05

LISP Survey

I stumbled across an interesting LISP article, Common Lisp Implementations: A Survey.

Mandelbrot in Mathematica

Just for laughs, a implemented a tiny Mandelbrot application in Mathematica.

mandelbrot =
  Compile[{{cx, _Real}, {cy, _Real}, {limit, _Integer}},
    Module[{count = 0, zx=cx, zy=cy, zx2=0, zy2=0, tx=0, ty=0},
      While[count <= limit && (zx2 = zx^2)+(zy2 = zy^2) < 4,
        ++count;
        tx = zx2 - zy2 + cx;
        ty = 2 zx zy + cy;
        zx = tx;
        zy = ty
      ];
    count
  ]
];

Manipulate[
  ReliefPlot[
    Table[
      mandelbrot[x, y, limit],
      {y, y0, y0 + x1 - x0, (x1 - x0) / resolution},
      {x, x0, x1, (x1 - x0) / resolution}
    ],
    ColorFunction -> colors
  ],
  {limit, 50},
  {resolution, 400},
  {x0, -2},
  {x1, 1},
  {y0, -1.5},
  {colors, Sort@ColorData["Gradients"]}
]

Wicket

Apache Wicket is yet another web framework that is getting some buzz.


2008-01-04

Scala

Scala is a programming language that seems to be largely a fusion of Haskell and Java.  As is the fad these days, it has its own web framework called lift.  I spent some time working with Scala, and it appears to be a promising successor for Java.  There is a growing, vocal community using it.

My attention was drawn back to Scala by Bruce Eckel's blog entry Java: Evolutionary Dead End.  Quite a few people in the blogosphere share the view expressed in a blog entry by n8han, The awesomeness of Scala is implicit.


Blog Archive