Kuro5hin.org: technology and culture, from the trenches
create account | help/FAQ | contact | links | search | IRC | site news
[ Everything | Diaries | Technology | Science | Culture | Politics | Media | News | Internet | Op-Ed | Fiction | Meta | MLP ]
We need your support: buy an ad | premium membership

[P]
A Shallow Introduction to the K Programming Language

By jjayson in Technology
Thu Nov 14, 2002 at 05:58:07 AM EST
Tags: Software (all tags)
Software

About two years ago I was introduced to a programming language that I really didn't like: it didn't have continuations, I didn't see any objects, it had too many operators, it didn't have a large community around it, it was strange and different, and it looked like line noise, like Perl, and I don't like Perl. However, I gave it a try.

I had to learn that continuations may not be there, but first-class functions are; it may not have a normal object system, but that is because the language doesn't need it and gets it power by cutting across objects; all the operators are the functions that make up its standard library; it's community may not be large, but it is incredibly intelligent; it only looks strange until you understand its concepts; and well, it will always look like line noise, but you will stop caring because this also make the concise code easier to read. K has since become my language of choice.


Introduction and Terminology

K is a high level system programming language available for Windows, Solaris, Linux, and maybe a few other Unix flavors upon request. It is mixture of APL, a functional programming language, and many unique features not found elsewhere. The K system is produced by Kx. They produce the language and one of the fastest commercial relational database available, KDB — written in K. You can get copies of the interactive interpreter free for educational, research, or toy purposes, and there is a non-interactive, runtime-only interpreter that is strictly free. I have heard rumors that there would be interest in opening up the language if there would be enough community response around it.

Contrary to some opinion, K is a real-world language, made for real use and sold as a real product. It is not a toy language. It is not a Turning tarpit language. It is not intentionally obfuscated or made to be intentionally strange, like Befunge or Intercal.

K was originally developed by Arthur Whitney, who was a very influential member of the APL community. Before K, Arthur was asked to write the Dr. Iverson's APL-successor, the J language, but he decided to go his own way. This isn't his first language either; he is also the creator of the Morgan Stanley financial language A+. From 1994 to 1997 the Union Bank of Switzerland purchased exclusive rights for the use of K, but now it is available to all of us.

One of the large draws of K is the extreme programmer productivity it offers, its incredibly fast execution speeds, and its very small executable units. One of the proofs of these claims is Brian Kernighan's Experiments with Scripting and User-Interface Languages, in which K easily outperforms other favorite languages. Another example of these claims met is how KDB outperforms Oracle on TPC benchmarks in both query speed and data storage size while essentially being written by one person. Also, K code is very dense, and it is typical to see 100:1 code size reduction when migrating to from C to K. I have heard of almost a 1000:1 reduction when a project moved from Java and SQL to K and KSQL (KDB's query language).

K is an exceptional language for dealing with mathematical analysis, financial prediction, or anything that handles bulk data. I have used it for a document search engine and other computational linguistic tasks. K doesn't work very well when the problem is not vectorizable and scalars are the largest datum to operate on. Often though, algorithms can be written in either method. However, some problems have been almost impossible to vectorize, such as Ackermann's function, and are not good to attempt in K.

K has bindings to other popular language such as C, Java, VisualBasic, and Excel. There has also been work done on bindings to Python and Mozilla's XUL. K's builtin interprocess communication and binary format for objects is very simple and documented so making other systems interact with K is often equally simple.

Even though K is an interpreted language, the source code is somewhat compiled internally, but not into abstract machine code like Java or Python. The interpreter can be invoked interactively or non-interactively, and you can also compile a source file down to a binary file for product distribution, if you wish.

One of the hardest things for many people to get over at first is the way K looks. Even the strongest K enthusiast will freely admit that K tends to look like line noise. I came from a Scheme background and already had my eyes hurt a couple times trying to learn Perl. When my roommate introduced me to K I ridiculed it and couldn't imagine ever wanting to use it. However, after a few sessions, my eyes began to relax. Unlike Perl, the syntax is extremely regular and there is almost no syntactic sugar or special cases. K is even translatable into English; there is a program that will take a K expression and produce its English translation. To allow this translation each operator is given is a short English name and sometimes small combinations of operators are also given common names. This is similar to building a vocabulary in a natural language. You will begin to look at larger segments of code and abstract away the actual details of what happens to the data, while understanding the higher-level concepts and transformations more easily.

To make even stronger connections with linguistics, grammatical terms are used to describe K. Operators are called verbs, and data is called nouns. There are also operators that modify other operators (these will be described later) that are called adverbs. Stringing some nouns, verbs, and adverbs together will produce clauses and sentences. This dialogue has been inherited from APL and is often abandoned for the more commonplace names of operators, functions, and variables.

Comments and Conventions

When small code segments are presented, I will use the conventions of the language and interpreter for comments and display. Forward-slash (/) is special when it comes at the beginning of a line or it has space to the left of it, then it starts a comment that lasts until the end of the line. Some people will also disguise comments as strings, since that will not effect the results of a computation. The interpreter prompts the user with two spaces to signify that it is ready to accept input. It will print all of its output without any leading space. I will do the same, showing interpreter input preceded by two spaces and interpreter output unindented.

K tends to favor simplicity over sugar. One thing that may confused people easly is K has no precedence rules. Everything is parsed from right to left. This makes it easy to see what happens next in a computation, but it also takes a little getting used to. For example, 3*2+1 in K will produce 9, instead of the more usual 7 in other language. This is always the case, except when a set of parentheses is come across. What ever inside the parentheses is first evaluated then normal evaluation resumes. People will frequently play with the order of their statements to reduce the number of characters in the expression, instead of placing parentheses around it.

Values

There are four simple types of values in K -- integer, floating point, character, and symbol; a special null type for the singular value of _n; and two composite types -- dictionaries and lists. The composite types are containers that others values may be stored and retrieved from. Lists are further classified as either homogenous or heterogeneous, and all homogenous lists carry the type of value they contain around with them. A list where all the simple elements are of the same type are called vectors. K is optimized to handle these homogenous lists and vectors since they appear in programming so frequently.

Lists are represented in different ways. The most general case is surrounded by parentheses with each element separated by a semi-colon. If the list is homogenous the parentheses and semi-colons will be elided and you will simply see the elements separated by a space. If all the elements are characters then the lists will be a string surrounded by double-quotes. To index a list you use brackets ([]) with multiple indices allowed. To index a multidimentional list use a semi-colon to separate the dimensions, but leaving a dimension blank selects all (this the same as using _n as the index).

A symbol is an interned string that the interpreter uses for variable lookup. They are created by the backtick followed by any legal variable name: a letter or underscore followed by any combination of letters, numbers, underscores, and dots -- but no more than two consecutive dots (since they have a special meaning that will re explained later). If you would like the symbol to not follow a legal variable name patters, you may enclose it in double quotes.

Examples:

  (1; 2.3; 4; 5.6)       / heterogeneous list of integers and floats
  1 2 3 4 5              / homogeneous list of integers
  1.2 3.4 5.6            / homogeneous list of floats
  "quack"                / homogeneous list of characters
  (1 2; 3.4 5.6; "meow") / a list of lists
  (1;2 3;4 5 6)          / a vector of integers

  "abcdefghijlkmnopqrstuvwxyz"[14 8 13 10]
"oink"

  ("qwerty";"poiuy";"asdf";"jhgfdsa")[;3] / slicing or projection
"ruff"

  `rusty
  `"http://www.kuro5hin.org"

Verbs

K is a very small language, so it needs to make the most of everything. Unlike APL, It uses only ASCII, so it already starts off with not too many characters to use and abuse. To allow for compact code operators are overloaded with two cases: a monadic (one argument) and diadic (two argument) use. Sometimes these uses are related and sometimes they are not. And each case the operator sometimes has slightly different behavior depending on the type or domain of the arguments.

Examples:

  !4      / enumerate: a list of integers from 0 to x-1
0 1 2 3

  5!3     / mod: the residue of the left modulus the right
2

  2!1 2 3 / rotate: spins right back-to-front left number of positions.
3 1 2

  ,2  / enlist: a one item list containing only 2
,2

  1,2 / join: forms one list of the left and right argument
1 2

  |1 2 3 / reverse: reverses a list
3 2 1

  0|1    / max: the maximum also boolean OR
1

  &1 2 3 4     / where: returns the number of units specified
0 1 1 2 2 2 3 3 3 3

  &0 1 1 0 0 1 / where: an important use to get the indices of the 1s
1 2 5

  0&1          / min: the minimum also boolean AND
0

  4<5    / less-than: predicate of "is the left smaller than the right"
1
  <7 4 9 / grade-up: sorts indices in ascending order
1 0 2

  =1 0 1 0 0 3 0 1 3 1 / group: groups all indices of same value
(0 2 7 9
 1 3 4 6
 5 8)

  2=0 1 2 3 4          / equals: compares values
0 0 1 0 0

  ?1 0 1 0 0 3 0 1 3 1  / unique: all unique elements in order seen
1 0 3

  1 0 1 0 0 3 0 1 3 1?3 / find: the first indice of the right in left
5

Variables and Bindings

K is a dynamically, strongly typed language and, variables are not declared, but they come into existence when you assign a value to it. This can be done anywhere, even in the middle of an expression since there is no distinction between statements or expressions. If you try to read a value from a variable that has not yet been assigned to, you will raise an error. There are also no pointers. In true functional style, when you assign to a variable a deep copy of the value is made (K does this lazily, though). Assignment is done via the colon and it is read as "gets" or "is." As a special case, when an assignment is the last thing in an expression, null is returned (this helps prevent cluttering up the display log). You can force the return of a value from an assignment statement by using a case of the monadic colon.

Examples:

  a:"moo"       / a gets the string "moo"
  b:!10         / b gets enumerate 10 (integer list from 0 to 9)
  :c:b          / c gets the value of b, but changes to b do not effect c
0 1 2 3 4 5 6 7 8 9

  :h:(g*2),g:1+2 / h get g times 2 join g, where g gets 1 plus 2
6 3

  g
3

User-defined Functions

Braces ({}) are used to create functions; they are the equivalent of lambda in Lisp. Often they are used then the resulting function is assigned to a variable, but sometimes not. To assist in making the code compact, if a function requires three or fewer arguments, K will allow you to implicitly use x, y, and z as the arguments. If you need more than three arguments you must declare them all. All functions return the value of the last executed statement, even if that statement return null. To call a function you use brackets (just like a list index). If you do not supply an argument when calling a function, it will project.

Examples:

  pyth:{_sqrt(x*x)+y*y} / notice the two implicit arguments
  pyth[30;40]
50.0

  pyth[3 15;4 20]       / cute huh.
5 25.0

  dist:{[x1;y1;x2;y2] _sqrt((x2-x1)^2)+(y2-y1)^2}
  dist[1;1;4;5]
5.0

  :d:dist[1;1]          / project or curry the first two arguments
{[x1;y1;x2;y2] _sqrt((x2-x1)^2)+(y2-y1)^2}[1;1]

  d[7;9]
10.0

  :e:dist[1;;4]         / project on first and third argument
{[x1;y1;x2;y2] _sqrt((x2-x1)^2)+(y2-y1)^2}[1;;4]

  e[2;6]
5.0

  inc:1+
  inc 8
9

System Functions and Variables

After running out of punctuation Arthur made system function. Every symbol beginning with an underscore is reserved for either a system variable or system function. System functions use infix, like their less readable cousins, but like user defined functions they cannot be overloaded with monadic and dyadic cases (in the next version of K this will be changed and users will be able to define infix functions and overload them with n-adic cases).

Examples:

  3_draw 5        / list of 3 random numbers from 0 to 4
2 2 4

  2_draw 0        / list of 2 random real numbers from 0 to 1
0.2232866 0.9504653

  4_draw-4        / deal: list of 4 random nonrepeating numbers from 0 to 3
2 0 1 3

  4 13_draw-52    / deal a deck of cards into four piles
(29 27 10 0 23 3 28 5 24 16 40 8 22
 51 20 36 47 18 31 26 11 44 37 38 9 13
 39 42 34 50 21 6 19 46 48 45 14 43 2
 33 49 4 25 41 30 35 7 32 17 1 12 15)

  1 3 4 5 7 9_bin 4     / binary search through list returning index
2

  1 3 4 5 7 9_binl 2 4 6 / binary seach for a list of numbers
1 2 4

  16_vs 543212    / vector from scalar: changes base to 16
8 4 9 14 12

  5 3 2_vs 21     / also does variable change of base
3 1 1

  5 3 2_sv 3 1 1  / scalar from vector: the inverse
21

  _host`kuro5hin.org        / returns ip address as integer
-815566008

  256_vs _host`kuro5hin.org / presentation form
207 99 115 72

Adverbs

This is where K starts to set itself from apart from most of the common programming languages in use today. You rarely write loops in K (KDB is 100% loop-free), instead you use adverbs. An adverb modifies a function, returning another function, changing the ways it operates over its arguments and what it does with it's return values. Here is a small selection of adverbs' usages (there are other uses that are not covered here).

  • Over (/) modifies a diadic function and will apply the function down a list, collection the result.
  • Converge (/) modified a monadic function and will continually apply the function to the previous result until either the initial value or the result of the preceding value is returned.
  • Scan (\) will apply the function down a list, collection all intermediate results (this is sometimes called trace). There is a trace analog to all usages of over.
  • Each (') will apply the function down lists of the same length (equal to the valence of the function).
  • Each-right (/:) will hold the left argument of the function and apply the function down the list of right arguments.
Examples:

  +/1 2 3 4          / plus-over (sum): is similar to 1+2+3+4
10

  +\1 2 3 4          / plus-scan: returns the intermediate values of +/
1 3 6 10

  |/5 3 7 4 2        / max-over: compares all items like 5|3|7|4|2
7

  ,/(1 2;(3 4;5);6)  / join-over: (1 2),(3 4;5),6
(1;2;3 4;5;6)

  ,//(1 2;(3 4;5);6) / flatten: explained below
1 2 3 4 5 6

  3 4_draw'-3 -4     / draw-each: (3_draw-3),(4_draw-4)
(1 2 0
 2 0 1 3)

  2_draw/:10 100     / draw-right-each: (2_draw 10),(2_draw 100)
(7 7
 45 91)
Let me break down flatten for you. Join is a function that takes two values. Over modifies join and the result is a function that now takes one argument (a list) and joins all the elements of that list. Looking at the above example, when join was given a nested list, it simple stitched all the elements into a single list, removing one level of depth. However, we would like to remove all level of depth. We want join-over again to remove another level of depth, and join-over again to remove another level of depth, until the list is completely flat. This is what converge will do for us. The second application of over takes this monadic function, join-over, and continually applies it until the result no longer changes. If we didn't want to flatten the topmost list, but instead we had a list of lists to flatten, we would only want to apply flatten to each element of the top-level list. That is what flatten-each (,//') would do. If we wanted to keep the top two levels of depth we would write flatten-each-each (,//'') and this is where things start too look like line noise.

Conditionals

Although rarely used, there are a few conditionals; most often used is the colon. It is similar to cond in Lisp: it takes pairs of arguments and an optional final argument. The first argument of each pair is tested for truth (0 is false, all other integers are true, anything besides an integer is an error). If it is true then the result of evaluating the second of the pair is returned. If it is false then the next pair is tested. If all the pairs have been exhausted, then the final argument is evaluated and the result returned. If there is no final argument and all the conditions are false, then null is returned.

Examples:

  :[0;"true";"false"]
"false"

  s:{:[x>0;"+"; x<0;"-"; "0"]} / returns the sign of x or 0
  s 4
"+"

  s -3
"-3"

Naive Primality Test

As in Nobody Expects the Spanish Inquisition, I will conclude the basics with a naive primality predicate and try to explain it.

  isprime:{&/x!/:2_!x}  / min over x mod right-each 2 drop enumerate x
  isprime 14
0

  isprime 7
1
Analyzing from right to left. We create a list of all integers from 0 to x (exclusive), then we remove the first two elements (2_), so we are left with a list from 2 to x (exclusive). Next we determine the residue of x and each of the numers in the list. Finally, we calculate the minimum of the residues. If the number is prime, then the lowest residue will be 1 and be considered true. If the number was composite there will be a 0 residue for some value.
  !14
0 1 2 3 4 5 6 7 8 9 10 11 12 13

  2_!14
2 3 4 5 6 7 8 9 10 11 12 13

  14!/:2_!14
0 2 2 4 2 0 6 5 4 3 2 1

  &/14!/:2_!14
0

The K-tree

Here is a quick, small look at one of the unique elements of K, called the K-tree. It falls nicely into the K philosophy of keeping things simple and powerful. The K-tree can be used for modularization of programs, as a scoping mechanism, for GUI design, and as a rudimentary object system.

All variables exist somewhere on the K-tree. To reference a variable you separate the name of the variable and each branch name with periods. The root of the tree is an empty symbol. For example, you might have a fully qualified variable named .branch.subbranch.variable.

A branch is really just a dictionary. If I were to assign a dictionary that contained symbols sym and bol to the variable .tr.ee then you would be able to access .tr.ee.sym and .tr.ee.bol. It goes the other way, too. If you were to create the variables .dict.ion and .dict.ary then the variable .dict would be a valid dictionary. This makes the language very reflective since you can now modify variables locations, scopes, and manually manipulate extents.

Whenever you are in the K environment you are always running in a branch of the K-tree. When the K interpreter starts it places you in the .k branch. You can move around the tree with the directory (\d) command. For example \d .tw.ig would create the new branch tw then create a subbranch ig. You can inspect all the variables in a branch with the list variables (\v) command. Often a script will begin with a change directory command and then define all of its variables in that (and maybe a few more) branches. This effectively uses the K-tree as a module system.

  \d .test          / create a new directory off the root
  \d ement          / create a sub-branch
  \d                / show the current directory
.test.ement

  new:`small        / put some values in the directory
  old:`big
  \v                / list the contents o
new old

  \d ^              / back up one directory in the tree
  \d
.test

  \v
ement

  ement             / inspect the value of ement
.((`new;`small;)
  (`old;`big;))

  .test.ement.new   / fully-qualified
`small

  ement.old         / partially qualified
`big

  ement`old         / index like an array
`big

Other Unique Elements of K

The K philosophy itself has some unique insights on how to treat data and the appropriate way to organize data for efficient processing, however within the language there are some features that you will not find in any other language:

K uses the tree to hold an attribute structure. These attributes are used for documentation strings, GUI representations, for other functionality in K, and for whatever you decide to use them for. Some of the programming environments for K make entensive use of attributes to store information about where functions are defined and other administrative information.

K also has a the concept of dependencies and triggers. They are used for efficient, demand-based calculation of data and executing callback code whenever a value is changes (this is how the timer system in K works). K will keep track of out of date dependencies for you and only do the minimal amount of work necessary to update values.

K has a unique, declarative GUI subsystem that is based around the K tree and triggers. It takes a minimal amount of work to put a GUI on your application. K takes the approach that you show variables and changes made to that variable on the screen are immediately reflected in the program without any work by you.

K's interprocess communication (IPC) and network communication systems is also based around callbacks and message handlers. There are simple K primitives that will ship entire K data structures around for you, or you may do it yourself. The goal of the IPC system is like the goal with rest of K, make it fast, simple, powerful, and highly useful.

In a time when programming languages are lacking in originality and are not bringing new ideas to the table, K succeeds where others fail. But K is not just a research language, not appropriate for real-world use. While the community may be small some of the users of the language are very big. With recent implementations by Island ECN and the US government, this looks to only be getting bigger, too. The next version of the language will fix many of the nagging holes and annoyances and take away the line noise factor that has pushed many away.

Here are some closing simple segments of K that are informative on how the K way of approaching a problem may be different:

  cut:{1_'(&x=*x)_ x:" ",x}
  cut "Scoop ate my spaces"
("Scoop"
 "ate"
 "my"
 "spaces")

  fibonacci:{x(|+\)\1 1}
  fibonacci 5
(1 1
 2 1
 3 2
 5 3
 8 5
 13 8)

  first:*:
  euclid:{first(|{y!x}\)\x,y} / Euclid's Algorithm
  euclid[24;40]
(24 40
 16 24
 8 16
 0 8)

Sponsors

Voxel dot net
o Managed Hosting
o VoxCAST Content Delivery
o Raw Infrastructure

Login

Poll
Would you try K?
o Yes 51%
o No 25%
o If if didn't look so ugly 22%

Votes: 108
Results | Other Polls

Related Links
o Scoop
o available for Windows, Solaris, Linux
o Kx
o KDB
o Arthur Whitney
o A+
o Experiment s with Scripting and User-Interface Languages
o K easily outperforms other favorite languages
o Ackermann' s function
o English translation
o Nobody Expects the Spanish Inquisition
o Also by jjayson


Display: Sort:
A Shallow Introduction to the K Programming Language | 162 comments (156 topical, 6 editorial, 0 hidden)
Interested about deep copying (4.25 / 4) (#6)
by xriso on Thu Nov 14, 2002 at 04:08:45 AM EST

If it is a completely data-oriented language (i.e. no pointers, references, etc.), does this mean that GC can be completely done using reference counts when a lazy copying system is used? This would seem to get over the problem of excessive memory copying (something I hate oh so much), yet also prevent having to deal with memory management.

A very interesting language, it seems! +1F
--
*** Quits: xriso:#kuro5hin (Forever)

exactly (5.00 / 2) (#10)
by jjayson on Thu Nov 14, 2002 at 04:50:17 AM EST

Memory allocation is done very efficiently. It uses a simple reference counting system, hoisting allocations out of critical areas. It has nice features like constant time joining of lists while still having constant time access. It optimizes multidimentional data of the same type (i.e., vectors) into single dimensional contiguous chuncks so it is very cache friendly.
_______
Smile =)
* bt krav magas kitten THE FUCK UP
<bt> Eat Kung Jew, bitch.

[ Parent ]
Interesting question, actually (5.00 / 3) (#17)
by Simon Kinahan on Thu Nov 14, 2002 at 06:34:38 AM EST

If it is a completely data-oriented language (i.e. no pointers, references, etc.), does this mean that GC can be completely done using reference counts when a lazy copying system is used?

Yes, but my understanding is that this is not necessarily the best approach. Many completely or partially referenceless languages actually use a copying collector. I believe this is because such languages also tend to have a high ratio of garbage to live data, and a copying collector runs in time proportional to the amount of live stuff, whereas a reference counting collector runs in time proportional to the amount of dead stuff.

Simon

If you disagree, post, don't moderate
[ Parent ]

No iraq, +1 (3.00 / 2) (#8)
by dreancha on Thu Nov 14, 2002 at 04:21:14 AM EST

... and you get extra credit for mentioning befunge :)

+1 FP (2.50 / 2) (#9)
by dvchaos on Thu Nov 14, 2002 at 04:33:25 AM EST

It's a well written 'clean' article. and is something different too.

--
RAR.to - anonymous proxy server!
Perl (2.50 / 2) (#11)
by carbon on Thu Nov 14, 2002 at 05:05:40 AM EST

Unlike Perl, the syntax is extremely regular and there is almost no syntactic sugar or special cases.

Actually, Perl5 has quite regular syntax: it just has a lot of a) special variables, all of which are listed and follow the pattern of having a single non-alphanumeric identifier, and b) having extremely weird syntax. Perl is one of my personal favorite languages, right up there with C++, so I suppose this is just my bias speaking. :-)

Is there anything in particular you found contradictory about Perl's syntax?


Wasn't Dr. Claus the bad guy on Inspector Gadget? - dirvish
no it doesn't (2.33 / 3) (#12)
by jjayson on Thu Nov 14, 2002 at 05:19:26 AM EST

Perl's grammar is probably not even context-free. It is disguisting. three examples of special syntax: map, qw, and print.

K shows you that you don't need confusing syntax and all the sugar of perl to get small programs. Larry Wall is a horrible language designer.
_______
Smile =)
* bt krav magas kitten THE FUCK UP
<bt> Eat Kung Jew, bitch.

[ Parent ]

Bah (none / 0) (#15)
by carbon on Thu Nov 14, 2002 at 06:05:29 AM EST

I have no idea what the problem with map is; it seems to be a similar (though not nearly as cool) mechanism to the append stuff you mentioned above. Could you explain?

If you'll check the guide, you'll see that the x/stuff/ form for any x is just an alias for quotes. The qw stuff is simply a special kind of string processing quote pair that isn't actually represented by quote characters. You'll notice this is consitent with the regex stuff as well.

Filehandle support in perl5 is syntaxtually crap, as they occupy a weird sort of niche in Perl's namespaces. This is a fault in Perl, and it's effectively going to be fixed (along with all the other known design faults, as far as I can tell) in the eventually-someday-hopefully coming Perl6. I'm not arguing that Perl is perfect (no language is), just that it's more useful and clean than you make it out to be.

Luckily, it isn't a major issue: you're limited to built-in filehandles anyways, since you cant reimplement the filehandle interface as you can with scalars, arrays, and hashes (cough, lists and dictionaries, arrays and hashes, cough) and tie. So there's no particular reason to deal with filehandles in any sort of generic way, since you're stuck with builtins in the first place.


Wasn't Dr. Claus the bad guy on Inspector Gadget? - dirvish
[ Parent ]
Bah? (none / 0) (#26)
by mishmash on Thu Nov 14, 2002 at 08:26:20 AM EST

Yes, it's possible.

tie *FH, 'My::FileHandle::Implementation'

Please see the "Tying FileHandles" section in the perltie(1) manpage.

[ Parent ]

Funny (none / 0) (#82)
by carbon on Thu Nov 14, 2002 at 09:41:32 PM EST

That part of my manpage explains that tied handles are not actually implemented in Perl. Maybe mine is outdated.


Wasn't Dr. Claus the bad guy on Inspector Gadget? - dirvish
[ Parent ]
and my dad could beat your dad... (none / 0) (#23)
by sholden on Thu Nov 14, 2002 at 07:26:05 AM EST

Perl's grammar is probably not even context-free. It is disguisting. three examples of special syntax: map, qw, and print.

It's certainly not context free, after all "the only thing that can parse Perl is perl" :)

It is pretty ugly, hence the makeover for perl 6.

K shows you that you don't need confusing syntax and all the sugar of perl to get small programs. Larry Wall is a horrible language designer.

The aim of perl isn't to "get small programs". The aim was to make text processing simpler than the existing tools allowed.

Of course aims change, and now perl has a much bigger 'niche'.

Larry Wall is not a horrible language designer by any stretch. K may very well be better than perl, but it doesn't have 15 years worth of baggage.

I also suspect that high school students who suck at math will find K very difficult, but they seem to manage with perl (and the world, especially the WWW is far worse for it...)

But anyway, who cares, different strokes for different folks. Everyone's brain isn't the same, some people actually like the way perl is, and some like python, some like lisp, and there's rumours of those who actually like befunge.

--
The world's dullest web page


[ Parent ]
umm... (none / 0) (#60)
by pb on Thu Nov 14, 2002 at 02:59:56 PM EST

Seeing as how K is a descendant of APL, and APL was developed starting in 1957, I'd say that K has a lot more than 15 years worth of baggage.  Still, it looks like a remarkably small and consistent--if funny-looking--language.

Perl, on the other hand, stole as much as it could from shell scripting, C, and awk, guaranteeing that it would be remarkably huge inconsistent--if familiarly funny-looking--from the start.

Of course, I love Perl, and I find K somewhat baffling, but this is most likely because I've been working with C and shell scripting for a while, and I (intentionally) never touched APL.
---
"See what the drooling, ravening, flesh-eating hordes^W^W^W^WKuro5hin.org readers have to say."
-- pwhysall
[ Parent ]

!(descended -> baggage) (none / 0) (#76)
by sholden on Thu Nov 14, 2002 at 07:43:38 PM EST

Seeing as how K is a descendant of APL, and APL was developed starting in 1957, I'd say that K has a lot more than 15 years worth of baggage.  Still, it looks like a remarkably small and consistent--if funny-looking--language.

Being descended from something doesn't add baggage (unless compatability is aimed for, as in say C++). The creation of K would have provided an opportunity to discard some baggage, if anything.

Perl 5 on the other hand still has 'format'...

Don't get me wrong, K looks very interesting, I voted +1FP, and if the language wasn't proprietary I would certainly waste some time playing with it.

--
The world's dullest web page


[ Parent ]
That is kind of what Peter is saying... (none / 0) (#100)
by jjayson on Fri Nov 15, 2002 at 02:17:01 PM EST

Being descended from something doesn't add baggage (unless compatability is aimed for, as in say C++). The creation of K would have provided an opportunity to discard some baggage, if anything.
This is the heart of Peter's point. During the initial development of Perl it could have taken its opportunity to discard some of the baggage of C, awk, and shell scripting, but it chose to be familiar looking at the beginning instead of clean and simple. Now it is none of the the above.
_______
Smile =)
* bt krav magas kitten THE FUCK UP
<bt> Eat Kung Jew, bitch.

[ Parent ]
It did (none / 0) (#115)
by sholden on Fri Nov 15, 2002 at 06:04:50 PM EST

But what I was saying is that the Perl language is 15 years old. It has built up 15 years worth of its own baggage. And it's open source and not restricted by international standards bodies...

It did in fact drop a bunch of baggage from the languages it descended from. Compare perl to awk for numerous examples.

--
The world's dullest web page


[ Parent ]
Design purity (4.00 / 1) (#30)
by mishmash on Thu Nov 14, 2002 at 10:16:10 AM EST

Larry Wall, in his 1999 Perl Conference speech:
You know, if [the periodic table] were a computer language, people would say it has too many ways to do the same thing. It has too many features that work too similarly, and at the same time it's missing key features of higher abstraction that would really help an MIT grad student. Elements do multiple inheritance of properties, which is evil. Strong typing is not enforced. Nothing should be made of carbon, because organic programming gives you too many ways to get into trouble. There are too many metals, too many gasses, and not enough semiconductors like silicon. There ought to be more elements like carbon. Everything should be made of carbon atoms. Silicon is only good for sand, it should be removed. If this were really object-oriented, electrons and quarks would have the same interface as atoms and molecules. There's not enough encapsulation of electrons in the metals. There's too much encapsulation in the lanthanides and the noble gasses. And why the heck do we need so many different noble gasses anyway? They don't do anything! Throw 'em into that big hole at the top of the chart. And don't get me started on isotopes!

The periodic table is a mess. It should be redesigned.



[ Parent ]
Arrogance (none / 0) (#32)
by yooden on Thu Nov 14, 2002 at 11:01:57 AM EST

So Perl is as important as the PTE? God and Wall follow the same rules?

[ Parent ]
Its true (none / 0) (#37)
by Peaker on Thu Nov 14, 2002 at 11:54:38 AM EST

The periodic table would make a horrible programming language.

Larry wall is a good demagog, not a good language designer.

[ Parent ]

So? (none / 0) (#55)
by bodrius on Thu Nov 14, 2002 at 02:40:43 PM EST

The periodic table is not a programming language, and Perl is not the periodic table.

What's the point of the comparison?

A programming language benefits from clarity and regularity. It's power is in letting the programmer build simple, understandable abstractions of complex systems. The aspiration of the programmer is to understand as much of the system implemented as it is humanly possible. It's goal is to help a mind build a comprehensible system with a particular purpose.

The periodic table (or what it represents) allows complex systems to rise from random events. It's power is in the complex interactions that let extremely complex systems develop for no particular purpose or reason. The aspiration of the scientist is to understand as much as possible of special cases, that would let humans do broad generalizations/predictions concerning system interactions too complex to understand as a whole. But the aspirations of the scientist have no bearing on the "goal" of the "table"... complexity is an obstacle for the scientist, but nature has no concerns about whether human minds can scale enough to understand its messy behavior as a sum of its parts.

Or does Larry Wall have in mind a computer language that gives birth to complex behavior beyond and independent of what the programmer wants to achieve with each particular program?
Freedom is the freedom to say 2+2=4, everything else follows...
[ Parent ]

A note (none / 0) (#83)
by carbon on Thu Nov 14, 2002 at 09:49:08 PM EST

To all the people who are about to or already have make scathing remarks regarding Wall's intelligence and ego in response to this quote: get a grip! It's obviously a joke! Sheesh.


Wasn't Dr. Claus the bad guy on Inspector Gadget? - dirvish
[ Parent ]
A Follow-up Note (none / 0) (#86)
by yooden on Fri Nov 15, 2002 at 03:54:44 AM EST

It was sure meant to be funny, but it was also said in defense of some of Perl's unique features.

[ Parent ]
Hey now (4.00 / 1) (#54)
by ph317 on Thu Nov 14, 2002 at 02:36:23 PM EST


Perl's grammar can certainly be confusing.  One of the greatest powers and greatest faults of perl is the fact that There's More Than One Way To Do It for just about anything.  Without emplying stupid tricks like varying whitespace, I could probably write a basic one-liner "Hello World" 20+ truly unique ways in Perl.

I've done a lot of Perl coding, and a lot of [insert 10 or so other random languages here] coding, and Perl does in fact "bug" me a lot of the time.  It's a bit too ambiguous and inconsistent at times.

But, that all being said, Larry Wall is a Great language designer in my book.  His language kicks ass in its own way.  Just because it doesn't suit you well, or doesn't suit a whole class of problems well, doesn't mean that it's not still a great language written by a great designer.

[ Parent ]

well... (none / 0) (#122)
by tin on Fri Nov 15, 2002 at 11:11:21 PM EST

'map' iterates over a list, performs an operation on each element, and returns a list of the results of  the operations. oh, it can take a block (of multiple expressions) or a single expression to perform the operation on the list elements, but acts the same both ways, so nothing special about it.

'qw' quotes word, just like it says. you give it a bunch of words, it quotes them for you. words being defined by text delimited by spaces. words, quoted. not so special

'print' prints a list to the currently selected filehandle, or a filehandle given to it. oh, it also prints $_ to the selected filehandle if nothing is passed, but that makes sense since $_ is set by most every iterating-type construct (for, while, map, etc). a bit special, but it's consistent with the rest of the language, so if you've learned it properly, it does exactly what you expect, nothing special.

note: i'm not a Perl pro who has the language memorized, so i looked up these with 'perldoc -f' to be sure my knowledge of how they worked is correct. it is :)

as far as special variables go, 'use English;' since Perl5 gives pretty, but long, alternatives to all the special vars. of course, the short versions are still available. yay for choices.

-justin
[ Parent ]

perl and c++ (none / 0) (#39)
by jefu on Thu Nov 14, 2002 at 12:03:25 PM EST

I have to say that when I see people who like Perl and C++, I have to admire their intelligence. Both languages seem to me to be written by people who enjoy befuddlement and confusion - and it seems to be my fate to be particularly liable to bef. and conf. Sigh.

It might just be my feelings of envy at other's ability, or resentment, or something talking, but both Perl and C++ also seem to be to suffer from a surfeit of really bad programmers. The Perl motto is "there's more than one way to do it", but (moan) does everyone have to do it every possible way in a program?

And why, oh why, does C++ really need ways to overload "+" and why, oh why, oh why do people need to actually do it?

I'll just stick to languages I understand. Haskell, C, APL, Python, XSLT and maybe K.

[ Parent ]

my three cents (none / 0) (#51)
by skyknight on Thu Nov 14, 2002 at 01:54:35 PM EST

Perl is a great language for building small tools. You can get things done quickly and easily if you know what you are doing. Unfortunately, it has a nasty tendency of being a "write only" language, since while one can write very good and legible Perl code, it is quite possible to write completely unintelligible gobbledygook that does in fact compile but nobody will ever be able to read/modify. Also, its lack of strongly typed variables and function argument specification are a nightmare in large scale software engineering situations involving more than one person when developers are sloppy about documenting how things are supposed to be called. Something like C++ or Java is much nicer in these situations because variable types and function argument declarations force code to be, to a degree, self-documenting.

C++ is a nice language when you have requirements for both a good SWE language, as well as something with blazing fast performance. It also provides for more finely grained control in OO programming than does Java, but the differences are minimal. The main things that bug me about Java are a lack of templates, operator overloading, and default parameters, but not having this don't cripple it. You just have to deal appropriately with the idioms of whatever language you are using. If man-time is more important to you than machine-time, then you're probably better off going the Java route, and as Java VMs get better and better, it becomes harder to opt for C++ solely on speed considerations. You might come to regret your decision when you're poring over C++ code trying to find where the memory hole is.

Python... I don't really have any appreciable experience using this language, but I'd like to learn more as it seems it is gaining more widespread support as of recent.



It's not much fun at the top. I envy the common people, their hearty meals and Bruce Springsteen and voting. --SIGNOR SPAGHETTI
[ Parent ]
I keep hearing this, and it's bullshit (5.00 / 3) (#67)
by tzanger on Thu Nov 14, 2002 at 04:00:59 PM EST

Unfortunately, it has a nasty tendency of being a "write only" language, since while one can write very good and legible Perl code, it is quite possible to write completely unintelligible gobbledygook that does in fact compile but nobody will ever be able to read/modify.

I'm sorry, but if you don't have the discipline to keep your code legible, then that is your problem. Don't blame the language. Maybe Python is for you; it forces you to keep your room tidy and in the manner befitting to the python designers. I prefer to keep my code the way I like it, indented the way I like it, and looking how I want it to.

I have the very real pleasure of working with two perl programmers whose n*10k line programs are legible and understandable, and modifyable. Don't blame your lack of discipline on the language.

Also, its lack of strongly typed variables and function argument specification are a nightmare in large scale software engineering situations involving more than one person when developers are sloppy about documenting how things are supposed to be called.

So fire their sloppy asses and hire real programmers. "use strict" and -wT are very good at keeping my code free of stupid little mistakes like $thisvar and $thsivar, and strict mode does keep you mortal in playing with how functions are declared and used.



[ Parent ]
right only? (none / 0) (#78)
by jefu on Thu Nov 14, 2002 at 08:05:09 PM EST

Perl does tend to be write only - in large part because the people who write it seem to be encouraged by the powers-what-am-in-perl to do everything every possible way.
<p>
And, I'll admit, I'm also biased by the huge numbers of bad perl programmers out there.  
<p>
I once took a 10K line perl program which consisted of about a dozen copies of the same thing with small variations and tried to figure out what it did.  It took a looonnnggg time and I was not pleased.  
<p>
I eventually rewrote it to a 2kloc perl program which did everything the first one did and a bit more - and using the same algorithms.  Then rewrote that to a less than 1kloc Python program , then rebuilt that to one that was about the same size, used a different approach and that did about 10 times as much and just as fast.  
<p>
You'll respond that it was the original programmer that wrote the bad code.  I agree completely.  But I'll also claim that perl does seem to attract the  bad programmers and does <b>NOT</b> do much to rein in their bad habits - bad habits which are often justified with appeals to the perl fallosophy(damn, there should be a good portmanteau of philosophy and fallacy) of "there's more than one way to do it".

[ Parent ]
oops (none / 0) (#80)
by jefu on Thu Nov 14, 2002 at 08:32:12 PM EST


I should apologize.  I know better than to indulge in language wars, and I understand only too well that I'm way, way too stupid to understand Perl and C++ and the like, so I'd prefer it if all and sundry would just ignore all the dumb comments I've made in  that kind of context today.

I'll now go hide and do penance or something.

[ Parent ]

You have some good points (none / 0) (#81)
by tzanger on Thu Nov 14, 2002 at 09:03:05 PM EST

And, I'll admit, I'm also biased by the huge numbers of bad perl programmers out there.

I was too at one point. I also hated javascript programmers because all the fucking language seemed to be used for was to obstruct my interaction with a web page. However XWT has changed my mind about them (and I are a jscript programmer too, now!).

Regardless, just because scum floats to the top of the pond it shouldn't make you hate the top of the pond.

I once took a 10K line perl program which consisted of about a dozen copies of the same thing with small variations and tried to figure out what it did. It took a looonnnggg time and I was not pleased.

Sounds disgusting. However Python (nor any strongly-typed, forced-formatting language for that matter) would not have helped you here.

You'll respond that it was the original programmer that wrote the bad code. I agree completely. But I'll also claim that perl does seem to attract the bad programmers and does NOT do much to rein in their bad habits

I agree -- 100%. There a lot of people who think they're cool cats just because they can make sixty characters which resemble line noise do something productive. They're poseurs, though, and you find them anywhere, not just in programming circles.

bad habits which are often justified with appeals to the perl fallosophy(damn, there should be a good portmanteau of philosophy and fallacy) of "there's more than one way to do it".

Just because there is more than one way to do it doesn't mean that 99% of those ways are good ways. :-) It's like fucking -- how goddamned boring would sex be if you could only do it one way? Sometimes the natural-language nature of Perl makes things a little hair-raising, this is true. But when it comes right down to it -- I want to be in control over the program, not the language. Perl gives me the (extreme) flexibility I want in a language, which is likely why it's so very popular.



[ Parent ]
Eh? Bullshit? (none / 0) (#113)
by skyknight on Fri Nov 15, 2002 at 05:18:53 PM EST

I think that you have grossly misinterpreted my comments. I happen to love Perl, and I happen to be very good at keeping it legible and maintainable. The fact that my code is such, however, does not result from language restrictions, but rather from my own discipline. It's the right tool for the job when I do lots of things, but it can be nightmarish when you have to figure out what someone else's stuff does. Consider the following piece of code which I often have the misfortune to come across when dealing with other people's stuff...



sub foo {
my $self = shift();
my $whatever = shift();
return $self->bar()->baz($whatever)->quux();
}

I always use the strict pragma, and you may note that it will do absolutely nothing to help in this instance. Answer me this from the code :

  • What kind of object gets passed in?
  • What kind of object gets returned?

If the developer had been kind, he would have put documentation above the method definition, but if he didn't, I'm really up shit creek sans paddle. If it had been in a strongly typed language I would have at least had some hints as to what was going on because it would have had a list of named and type parameters, and a typed return value. To deduce how this function works, I will have to dig around until I find some code that invokes it, see what it takes as an argument, figure out what type that thing is, and then either fire up the debugger or add a print ref($thingy) code snippet to examine the return value.

Perl is often the right tool for the job, and it's one of the first languages that I learned. I love using it, but I really loathe having to look at other people's code when they don't have good habits. At least a strongly typed language forces some minimalistic good habits on them. How is saying this bullshit? :-/



It's not much fun at the top. I envy the common people, their hearty meals and Bruce Springsteen and voting. --SIGNOR SPAGHETTI
[ Parent ]
Discipline: that was my whole point (none / 0) (#118)
by tzanger on Fri Nov 15, 2002 at 07:27:13 PM EST

I think that you have grossly misinterpreted my comments. I happen to love Perl, and I happen to be very good at keeping it legible and maintainable. The fact that my code is such, however, does not result from language restrictions, but rather from my own discipline. It's the right tool for the job when I do lots of things, but it can be nightmarish when you have to figure out what someone else's stuff does.

If that person didn't have the discipline to comment it, use "use strict" or use clear variable names and functions, I agree with you. I maintain that that is not the language's fault.

Your code block is the perfect example of a lazy/undisciplined programmer. Is it perl's fault? Should you need a license to use Perl? I can't answer your questions any better than you could without looking at the whole program. However that is irrelavent; any programmer working under me who had such shitty coding skill would be warned twice and then let go.

Perl is often the right tool for the job, and it's one of the first languages that I learned. I love using it, but I really loathe having to look at other people's code when they don't have good habits.

I loathe looking through anyone else's code who doesn't have good programming/documentation practices. That is in Perl, Java, C/C++, shell scripting, you name it. Strong types don't help you much to overcome shitty programming. That is what I'm referring to as bullshit: the idea that having strong data types can save you from the horrors of looking at a shitty programmer's programs.



[ Parent ]
Analogy (4.00 / 1) (#120)
by skyknight on Fri Nov 15, 2002 at 07:50:12 PM EST

First off, you have to understand my situation. Having just graduated from college I'm the person in the position to be fired, not to do the firing. As such, I can only make helpful hints when I see problem code, not axe people. Now for an analogy...

Why do highways have guard rails? If you drive off of the road, you're quite possibly an idiot, and it's often your own damn fault. The guard rails, however, are there not just to save you from crashing into a tree of going off of a cliff... The problem is that bad drivers don't just kill themselves; they kill other people too. Guard rails keep people from doing things that cause lots of collateral damage, such as driving across the median strip and killing people in oncoming traffic, or crashing through residential areas and killing people in their houses. Software controls can do the same thing to minimize the propagation of the effects of sloppy habits.

Do we really need a tool like CVS? No, we could get by without it if there were perfect communication and coordination between developers. We use it because it makes life more sane. Another perfect example is member access control in good OO languages like C++ or Java. Do we really need to specify a piece of member data as private? No, of course we could just rely on users never to access it inappropriately, but explicitly and proactively preventing access to it can save a potential debugging nightmare later. To quote Programming Perl, "Perl doesn't have an infatuation with enforced privacy. It would prefer that you stayed out of its living room because you weren't invited, not because it has a shotgun." Sometimes, however, it's nice to have a shotgun.



It's not much fun at the top. I envy the common people, their hearty meals and Bruce Springsteen and voting. --SIGNOR SPAGHETTI
[ Parent ]
Auto analogies never work right (none / 0) (#124)
by tzanger on Sat Nov 16, 2002 at 10:55:47 AM EST

Why do highways have guard rails? If you drive off of the road, you're quite possibly an idiot, and it's often your own damn fault. The guard rails, however, are there not just to save you from crashing into a tree of going off of a cliff... The problem is that bad drivers don't just kill themselves; they kill other people too. Guard rails keep people from doing things that cause lots of collateral damage, such as driving across the median strip and killing people in oncoming traffic, or crashing through residential areas and killing people in their houses. Software controls can do the same thing to minimize the propagation of the effects of sloppy habits.

As I said in the title, auto analogies are never quite on-spec. Guardrails are there for safety and to save lives. You can hit a patch of ice going around a bend. What's the analogy in software? Coding drunk? I don't know.

At any rate, the guardrails don't prevent you from driving, and they don't enforce you to drive with your hands at 3 and 9, no cell, no radio, no talking passengers. Strict typing, forced formatting... that is what they do: they force you to code a certain way. Sure, it forces you to some standard of coding, but it does nothing to prevent you from implementing sloppy or wasteful algorithms, from "copy and paste" coding, nor does it in any way make you a better programmer.

Do we really need a tool like CVS? Absolutely. It is a tool, not a shackle. You can still use CVS badly but it doesn't enforce a method or a style of programming on you.

To reiterate, nothing is going to make poor programmers better if they aren't willing to try and gain the discipline they need, and the time to practise and study the language. You can write shit code in any language. Whether that shit code looks pretty or not does abolutely nothing for me; shit code is shit code.



[ Parent ]
Examples, please. (none / 0) (#116)
by Shpongle Spore on Fri Nov 15, 2002 at 06:28:36 PM EST

Maybe Python is for you; it forces you to keep your room tidy and in the manner befitting to the python designers. I prefer to keep my code the way I like it, indented the way I like it, and looking how I want it to.

You know, I'm constantly hearing people piss and moan about Python, mostly regarding indentation sensitivity, but I've yet the worst problem I can even imagine being caused by is if you want to mix tabs-and-spaces and all-spaces indentation styles in the same file. Can you post an example (indentation-related or otherwise) of how Python forces you to do something in a way you find distasteful? I'm honestly confused about what people have against Python.
__
I wish I was in Austin, at the Chili Parlor bar,
drinking 'Mad Dog' margaritas and not caring where you are
[ Parent ]

Overload +? (5.00 / 1) (#57)
by der on Thu Nov 14, 2002 at 02:43:57 PM EST

Because my_string + "hello" is alot nicer than my_string.concatenate("hello");.

Or, say you have a complex number class (or some sort of number class you needed for whatever reason); which is nicer:

Complex n1;
Complex n2;
Complex n3;

n1 = n2 * (n3 - n1);

OR (without operator overloading)

Complex n1;
Complex n2;
Complex n3;

n1 = n2.multiply(n3.subtract(n1));

I'll take the operator overloading thanks. ;)



[ Parent ]
Or like Java... (none / 0) (#157)
by ekj on Wed Nov 20, 2002 at 12:17:26 PM EST

Or like Java: "We know better than you". First they decide that operator overloading is evil and should not be supported. Then they discover that well, it's actually pretty practical to be able to write:

"Hello " + name + " how are you doing ?"

And then they go break their own rules. String in Java has the + operator overloaded, inspite of the fact that you cannot do this in Java.

Ofcourse, noone would ever want to add one Integer to another Integer, so no reason to do the same for that class....

Inconsistencies suck. If you have to break your own rules even when making the base classes for a new language, this migth be a hint that those rules are not so clever afterall...

[ Parent ]

overloading "+" (none / 0) (#117)
by Shpongle Spore on Fri Nov 15, 2002 at 06:42:43 PM EST

And why, oh why, does C++ really need ways to overload "+" and why, oh why, oh why do people need to actually do it? I'll just stick to languages I understand. Haskell, C, APL, Python, XSLT and maybe K.

I assume you mean overloading "operator+" on the built-in data types, right? Because Python lets you overload to your heart's content, and Haskell lets you define whole new operators fer chrissake! Not that I think that's anything against either of those languages; I'm quite fond of both, unlike C++, which I hate with a passion beyond words after years of being forced to use it on the job.
__
I wish I was in Austin, at the Chili Parlor bar,
drinking 'Mad Dog' margaritas and not caring where you are
[ Parent ]

much ado over loading (none / 0) (#160)
by jefu on Wed Nov 20, 2002 at 09:19:35 PM EST

OK, OK.

I exaggerated a bit. I don't mind overloading when its reasonable, for instance "+" for strings or numeric types as long as I can figure out whats up without too much pain.

I don't find the Python (or Sather - sigh, a language dead long before its time) rules for overloading all that bad. Both languages have rules that say that "+" translates to a routine of a specific name. Further, the object semantics in both languages make the parameters passed and returned much easier to follow.

The Haskell overloading "instance foo ..." bothers me a bit more and a bit less. (Go fig. "Do I contradict myself, very well then, I contradict myself.") Since it is clearly just an extension of the interface notion (from Java - or rough equivalents in other languages) the fact that it can be used to overload things like "+" looks relatively clean. And I'll admit too that I quite like being able to define functions with names that aren't just "begins with an alphabetic and followed by ...." and infix functions.

In the Haskell context, lots more seems reasonable, perhaps. Non-strictness buys you so much as does the lack of side effects.

I'll admit too that the fact that overloading (say) "+" in C++ requires fun idiocies like jiggery-pokery on the stack with references leaves me more than a bit intimidated. But I also know that I'm nowhere near a good enough programmer to use C++. ("I have much to be modest about.")



[ Parent ]

What's good enough? (none / 0) (#161)
by Shpongle Spore on Wed Dec 04, 2002 at 02:27:49 PM EST

But I also know that I'm nowhere near a good enough programmer to use C++.

Using C++ effectively takes a lot of skill, but I'd say it's better to be a good enough programmer to avoid C++ than good enough to use it.
__
I wish I was in Austin, at the Chili Parlor bar,
drinking 'Mad Dog' margaritas and not caring where you are
[ Parent ]

perl is driven by natural language constructs (5.00 / 1) (#64)
by Dr. Zowie on Thu Nov 14, 2002 at 03:15:52 PM EST

I just got to hear a 3-way shootout discussion between the creators of perl, Smalltalk, and Python. They were done the way they were for very different reasons. In particular, I was struck by what Larry Wall had to say about his language design -- he asserted that he was/is aiming for something as close to a natural language (like English) as possible, while still retaining precision. English sure ain't context-free, and perl isn't either.

OTOH, I use perl (with the PDL extension) for scientific programming and find it amazingly powerful and useful. In particular, the behind-your-back typing that people complain about is one of the best language features. Contrast IDL, a language with strong typing in which all FOR loops break by default after 32767 iterations (because FOR loop variables are shorts by default).

Behind-your-back typing demonstrates what, IMHO, is so great about perl and lacking from more rigidly structured languages like K: perl constructs are carefully designed to do what you probably wanted if you're sloppy, and to do precisely what you say if you're precise about saying it, in keeping with Larry's natural-language bent.

Certainly, it's possible to write idiomatic or hard-to-read perl. Perl programmers, like UNIX sysadmins, tend to learn the environment a little at a time. A perl guru, like a UNIX guru, is anyone who (A) knows how to read man pages and (B) knows a little more than you. Unreadable perl was usually written by someone who knows a different corner of the language than you do. At my old job, people complained that my perl scripts looked like line noise -- it turned out that's because they couldn't read regular expressions.

Simplicity, power, flexibility: pick two. It appears to me that K is based around the first two, and perl is based around the last two. Teaching languages like BASIC or PASCAL tend to go for the first and last.

[ Parent ]

Ah - regular expressions. (none / 0) (#70)
by static on Thu Nov 14, 2002 at 06:07:57 PM EST

I think a lot of people learn regular expressions early on and then tend to overuse them. "If all you have is a hammer, then everything looks like a nail." REs tend to be a language-within-a-language in Perl and I think not enough Perl programmers realize that.

I learnt string scanning in SNOBOL4 long before I even knew what regular expressions were. I now know both, of course, and this makes me wary of just bunging in an RE for some string scanning. This is especially so in PHP where the RE engine is not as well integreted as in Perl.

Wade.


[ Parent ]

some contradictions in the article though... (none / 0) (#121)
by tin on Fri Nov 15, 2002 at 10:34:46 PM EST

special cases:
x,y,z default variables if none are defined for a function
colon as assignment and as conditional, depending on syntax

i'm not saying special cases are bad. i love Perl's  use of context to add functionality. i just hate it when people try to put it down on account of these things.

also, either the article had a typo, or K has even more special cases:
3_draw 5        / list of 3 random numbers from 0 to 4
ok, i see the 3 numbers and the 5 elements of 0 to 4
2_draw 0        / list of 2 random real numbers from 0 to 1
not ok, i see the 2 numbers, but why does the last 0 turn into 0 to 1. i would think a 2 would be needed to create the TWO elements in 0-1
4_draw-4        / deal: list of 4 random nonrepeating numbers from 0 to 3
ok, this matches the first one.

-justin
[ Parent ]

+1 FP (4.00 / 1) (#13)
by daragh on Thu Nov 14, 2002 at 05:37:43 AM EST

Great article, well written. I love hearing about esoteric and new programming languages. I just have to persuade the powers that be to let me use them...

No work.

Nice article, some questions. (5.00 / 2) (#14)
by a2800276 on Thu Nov 14, 2002 at 05:48:53 AM EST

I came from a Scheme background Somehow, I knew this instinctively from the point that I'd finished reading the first couple of sentences :) So, if you don't mind my asking: What exactly is a continuation? I've looked around, but haven't found anything in google or foldoc that satisfies my curiosity. I take it that it's a rather academic description of a language feature.

Also, and this may sound trollish but isn't meant to be: what is APL still used for except in really archaic systems?

&1 2 3 4 / where: returns the number of units specified
0 1 1 2 2 2 3 3 3 3

&0 1 1 0 0 1 / where: an important use to get the indices of the 1s
1 2 5
I don't think I understand the concept of the "where" function. What does it do? In the second example it lists the positions in the list that contain 1s, but in the first example?

Ok, I think I just figured it out: Each index is listed x number of times where x is the value at the index-th position in the list. I think. You might want to clarify that...

I also got kindof lost in the system function section: the first argument gets "attached" (i.e. no spaces) to the function, correct? 1_draw 5. But what is the difference when further attributes are a.) seperated by a space (2_draw 5), seperated by a dash (4_draw-4) and c.) not seperated at all:

1 3 4 5 7 9_binl 2 4 6 / binary seach for a list of numbers
1 2 4
(This one I definately don't understand)

All in all great article! Could maybe have profited a little by being cut into pieces and expanded, but ...

spacing issues, _bin, and _binl (5.00 / 3) (#16)
by jjayson on Thu Nov 14, 2002 at 06:21:54 AM EST

I also got kindof lost in the system function section: the first argument gets "attached" (i.e. no spaces) to the function, correct? 1_draw 5. But what is the difference when further attributes are a.) seperated by a space (2_draw 5), seperated by a dash (4_draw-4) and c.) not seperated at all:

The first arguement doesn't need to be attached to the function name. I just don't use much whitespace, as you will notice. You could have space between the left argument and the function name if you wanted to. For the most part spacing isn't important (but there are a few gotchas).

The case of draw where it has a negative right argument is called deal. It will generate unique random numbers from the correct range and the left argument must not be greater in magnitude than the right argument, obviously since "6_draw-5" would say to chose 6 unique numbers from the range of 0-4 and there are only 5 possible choices.


  1 3 4 5 7 9_binl 2 4 6 / binary seach for a list of numbers
1 2 4

(This one I definately don't understand)

_binl searches for right arguments in the left list argument. Just take the right arguments one at a time:

  1 3 4 5 7 9 _bin 2
1
  1 3 4 5 7 9 _bin 4
2
  1 3 4 5 7 9 _bin 6
4

The search is a binary search so the left argument must be ordered.  If the number is not found the index of where the item should be inserted to keep the list in order would be returned. Since 2 fits between 1 and 3, that would be index 1. 4 is found at index 2 obviously. 6 fits between 5 and 7 at index 4.

"1 3 4 5 7 9 _binl 2 4 6" is semantically equivalent to "1 3 4 5 7 9 _bin/: 2 4 6".

Here is another example:

  2 4 6 8 10 _bin 8
3
  2 4 6 8 10 _bin 9
4
  2 4 6 8 10 _bin 10
4
  2 4 6 8 10 _bin 11
5

Does this clean things up a little?
_______
Smile =)
* bt krav magas kitten THE FUCK UP
<bt> Eat Kung Jew, bitch.

[ Parent ]

Ok, I see where I lost you.... (none / 0) (#21)
by a2800276 on Thu Nov 14, 2002 at 07:17:46 AM EST

If the number is not found the index of where the item should be inserted to keep the list in order would be returned.

That's exactly the point I was missing, thanks!

[ Parent ]

Continuations (4.00 / 1) (#19)
by TuringTest2002 on Thu Nov 14, 2002 at 06:40:19 AM EST

I answer from a non-user of continuations, just learned the concept for I was curious over it. So I will describe it in an intuitive manner.

Continuations is basically a function-calling mechanism different of the common program stack (call - return). With continuations, instead of a call stack you have a call tree.

When you continue from function A to function B, control is transferred to the new context frame like with a GOTO (i.e. no return point), but the calling context is not destroyed. So if you latter call A from B or from whatever you are, A donsen't restart from the beginning but from the point it last where executing.

You can see it like an inter-process comunnication mechanism with each function acting as a process and without a central preemptive scheduler.

[ Parent ]

Continuations... (5.00 / 3) (#20)
by mirleid on Thu Nov 14, 2002 at 06:45:39 AM EST

A continuation is something very complicated to explain decently, and very simple to explain in simplistic terms. I'll take the second approach :-)...

A continuation is what a program would do if it were allowed to pursue its normal course at a given point in time. Taking the following C snippet:

int multiply_x_by_10_y_times(int x, int y)
{
  for(int f=0; f<y; f++)
  {
    x *= 10;
  }
  return x;
}

Now, if you call this function with arguments x=1 and y=4, you'll get get 10000 back. When the program is done (assuming all that it does is call this function with the parameters presented above) its continuation is empty. But, what if you can freeze the program at the time that it has done 2 iterations (still 2 to go)? What remains to be done is called the continuation of the program at that point. Scheme (and maybe K) allows you to "store" in a variable what the program would do if it were allowed to continue uninterrupted. You can use this variable at a later time to resume the execution at the point where the continuation that is stored in the variable was captured. If you are interested in digging into it in a little more detail, have a look at this introduction to Scheme and how to implement it. Since the goal of the document is to try to describe strategies to implement the concepts, it might give you more familiar concepts to hang on to while trying to figure out what continuations are really about.



Chickens don't give milk
[ Parent ]
a good introduction to continuations in scheme (5.00 / 1) (#66)
by sesquiped on Thu Nov 14, 2002 at 03:44:42 PM EST

is here.

[ Parent ]
Proof? (5.00 / 11) (#18)
by obsidian head on Thu Nov 14, 2002 at 06:37:22 AM EST

One of the proofs of these claims is Brian Kernighan's Experiments with Scripting and User-Interface Languages, in which K easily outperforms other favorite languages.

I read the entire thing.  Where does it mention K?

Look at the next link (5.00 / 1) (#42)
by jjayson on Thu Nov 14, 2002 at 12:48:17 PM EST

The link in the next sentence has all the problems from the test written and the stastics of run-time speed and code size compared aginst the other languages. It is very informal but show very well how K is suited to a variety of tasks.
_______
Smile =)
* bt krav magas kitten THE FUCK UP
<bt> Eat Kung Jew, bitch.

[ Parent ]
More conspiracy (5.00 / 2) (#53)
by jtra on Thu Nov 14, 2002 at 02:05:08 PM EST

False claims are bad. But there is more to it.

Look at text written by Cal Bunny about K language. There are whole paragraphs are same.

So, did jjayson copycat this? Maybe, but when you look at both user info/comment rating you will some correlation, they have a lot of mutal 5.00/1 votes. He also claims in his diary: "I am not jjayson, I am not nodsmasher, I am not mami, I am not mrgoat, I am not mrqueue, I am not ana or any body but bunny vomit.". But giving a comment rating of 5 (and never giving them less), even on silly and empty comments (1 |2 |3 |4 ) between small set of users is strange. I see a conspiracy here.

--Get textmode user interface for Ruby, http://klokan.sh.cvut.cz/~jtra/
[ Parent ]

Ah yes. (5.00 / 1) (#56)
by pb on Thu Nov 14, 2002 at 02:43:50 PM EST

It's a CONSPIRACY, I tell you!  A conspiracy of K users--that ever so popular language is sure to bring the imitators and conspirers out of the woodwork!

Maybe it looks that way to an outside observer, but I wouldn't worry. I think that jjayson and Cal Bunny actually have a pretty friendly relationship--I'm sure they made sure it was ok first.

But who knows, maybe Cal Bunny will notice and clear everything up for you!
---
"See what the drooling, ravening, flesh-eating hordes^W^W^W^WKuro5hin.org readers have to say."
-- pwhysall
[ Parent ]

All my hard work, stolen! (4.00 / 6) (#59)
by Cal Bunny on Thu Nov 14, 2002 at 02:58:31 PM EST

I work to learn a new interesting programming language, I learn enough English to write an essay, I learn to type with my back paws since my front paws are temporarily paralyzed from over ingestion of carrots, I work 12 hours a day to support my large family and use all my free time to write something I think the Kuro5hin readers would appreciate. This is the thanks I get from the community!?

My blood and sweat is stolen without even giving me a single line of credit! I demand that rusty take this story down or I will sue Kuro5hin for assisting in copywrite infringement.

What's wrong Jjayson, do you have a studdering problem? Couldn't you have done another wacko story on the homeless people again or some other knee-jerk liberal cause? Did you get tired of people voting down your thinly veiled attempts at religious preaching?

Go write your own story next time and leave the bunnies alone. You probably wouldn't have done this if I was a wolf or a bear. This is pure animalism. You are just jealous my cute fluffy tail big floppy ears. Well you can't have those either.


^cb^
[ Parent ]

Stop your complaining. (3.66 / 3) (#61)
by jjayson on Thu Nov 14, 2002 at 03:01:13 PM EST

I should just make bunny stew out of you like I did with your mother.
_______
Smile =)
* bt krav magas kitten THE FUCK UP
<bt> Eat Kung Jew, bitch.

[ Parent ]
Cal Bunny.. (5.00 / 2) (#71)
by infinitera on Thu Nov 14, 2002 at 06:19:50 PM EST

was once known as Cal Jayson, before the bunny craze swept through k5. Perhaps that should give you a hint. ;)

[ Parent ]
min/max and/or (4.50 / 2) (#22)
by Karellen on Thu Nov 14, 2002 at 07:21:08 AM EST

if | is both a `boolean or' and `max' operator, I can see how that works for `0|1', but how does it work for `0|-1'?

Boolean or should be true (non-zero), but the max of those two is zero. How does that work?

Excellent question which reveals the heart of K (5.00 / 1) (#35)
by WilliamTanksley on Thu Nov 14, 2002 at 11:45:54 AM EST

So you want to know how one can do bitwise operations when your boolean operations double as min and maxes? You've just hit on one of the inventions of the genius who made APL.

If you want to operate on the bits of a number, you essentially want to treat the number as a special kind of array of bits -- and K is utterly brilliant at working with arrays.

\ so, first convert the number to an array of
\ 0s and 1s:
bitwise: 2 _vs
\ Then operate on the resulting array.
(bitwise 1024) & bitwise 1024+256

The result can be converted back to a number at will using the '_sv' function (the name is mnemonic for "vector to scalar").

The compiler optimises this common case, of course, so the computer will probably handle this entire operation as a simple 'and' instruction.

I didn't mention how to handle arrays of different length, which is important in real applications -- obviously you don't want to get a length error just because 256 produces a 9-element array, while 1024 produces an 11-element array. But I think the answer here covers the question well enough; the nitty-gritty can wait.

Great language. Needs to be opened.

-Billy


[ Parent ]

_vs returning vectors of the same length (5.00 / 1) (#41)
by jjayson on Thu Nov 14, 2002 at 12:46:24 PM EST

K4, the next version of K coming out of the pipe, will have a true single bit type (as well as integers of various other bit sizes). However K currently has a weekness in playing with bit vectors. I have never found it to be an issue, but for some applications people might.

To get _vs to return to compatible lists for running and/min/or/max over, give _vs two values to convert at the same time

  tobinary:2_vs
  tobinary 1 25     / convert 1 and 25 to binary
(0 1
 0 1
 0 0
 0 0
 1 1)

  +tobinary 1 25      / flip the result
(0 0 0 0 1
 1 1 0 0 1)

  |/+tobinary 1 25    / then map OR/MAX over it
1 1 0 0 1

  |/'tobinary 1 25    / or just map over-each instead =)
1 1 0 0 1

_______
Smile =)
* bt krav magas kitten THE FUCK UP
<bt> Eat Kung Jew, bitch.

[ Parent ]
only boolean when 0s and 1s (5.00 / 1) (#47)
by jjayson on Thu Nov 14, 2002 at 01:10:36 PM EST

max/min can only be considered and/or when dealing with vectors of 0s and 1s. It isn't a true bitwise operator, so "0|-1" is 0.
_______
Smile =)
* bt krav magas kitten THE FUCK UP
<bt> Eat Kung Jew, bitch.

[ Parent ]
I didn't think you meant it was a bitwise op... (none / 0) (#75)
by Karellen on Thu Nov 14, 2002 at 07:34:00 PM EST

Huh, I thought by `boolean OR' you meant `logical boolean OR' (equivalent of C's `||'), not `bitwise boolean OR' (`|').

Or did you?

OK, now I'm confused.

`0|-1 = 0' isn't true if `|' is a logical boolean OR operator, or if it's a bitwise boolean OR operator, but only if it is a `max' operator.

So what you acutally mean is that the `|' operator itself can only operate properly on vectors of 0s and 1s, as it's useless in any other context?

K.

p.s. Does that mean you have to type:

:[x != 0 & y != 0; "x or y"; "neither"]

instead of:

:[x | y; "x or y"; "neither"]

(And that's assuming the `!=' (or equivalent) operator exists for `not equal'. I couldn't find the actual `not equal' operator in your list, but if that's not available either, then we get the even more baroque:

:[x < 0 | x > 0 | y < 0 | y > 0; "x or y"; "neither"]
)

Gosh.

[ Parent ]

It is far simplier than that (and not-equal) (none / 0) (#79)
by jjayson on Thu Nov 14, 2002 at 08:05:11 PM EST

Sorry for the confusion. diadic (i.e., when given two arguments) | is always max and diadic & is always min. always. These just happen to mimic max and min (repectively) when given a integers values of only 1 and 0. There are no true bit array in K (although the next version of K has bit arrays).

:[x|y;"x or y";"neither"] will work as you would expect.

To answer a side question, there is not not-equals operator, compare for eqality (=) then negate (~).

  ~0
1

  ~1
0

  ~2
0

  3=4
0

  ~3=4
1

  1 2 3 4 5=0 2 1 4 5
0 1 0 1 1

  ~1 2 3 4 5=0 2 1 4 5
1 0 1 0 0
_______
Smile =)
* bt krav magas kitten THE FUCK UP
<bt> Eat Kung Jew, bitch.

[ Parent ]

You meant `happen to mimic or and and', right? (none / 0) (#112)
by Karellen on Fri Nov 15, 2002 at 05:14:27 PM EST

In which case:

[x | y; "x or y"; "neither" ] will only work as I'd expect as a C programmer if x and y are positive or zero.

If x and y are integers that can contain any legal value, including negative numbers, I would have to do:

[ ~x=0 | ~y=0 ; "x or y"; "neither" ]

as the equivalent of

x | y ? "x or y" : "neither";

Right? (Assuming I'm not falling foul of any operator precedence rules).


[ Parent ]

you have the right idea. (none / 0) (#114)
by jjayson on Fri Nov 15, 2002 at 05:33:05 PM EST

If you want min/max to work the same way they do in C, e.g., negatives are considered true, then use negate (~) to coerce a value to be 0 or 1.
  ~-1
0
  ~~-1
1
  (0|-1)
0
  (~~0)|~~-1)
1

  ~-1
0
  ~~-1
1
  0|-1
0
  (~~0)|~~-1
1

  f:{:[(~~x)|~~y; "x or y"; "neither"]}
  f[0;0]
"neither"

  f[0;-1]
"x or y"
I know there is a shorter way that was in some email, but I can't remember it right now. sorry.
_______
Smile =)
* bt krav magas kitten THE FUCK UP
<bt> Eat Kung Jew, bitch.

[ Parent ]
thanks for the arcticle (3.00 / 2) (#24)
by mreardon on Thu Nov 14, 2002 at 08:08:53 AM EST

You've got me interested. I want to investigate more. Cheers.

Searching (3.66 / 3) (#52)
by nklatt on Thu Nov 14, 2002 at 01:55:21 PM EST

Be sure to let us know the google search phrase you come up with.

[ Parent ]
It's not Free (3.28 / 7) (#25)
by yooden on Thu Nov 14, 2002 at 08:10:44 AM EST

I have heard rumors that there would be interest in opening up the language if there would be enough community response around it.

Please come back when it's done. I use a Free OS and Free apps, why would I want to spend time on a non-Free language that may or may not be opened up (whatever that means) sometimes?

there... (4.50 / 4) (#34)
by Work on Thu Nov 14, 2002 at 11:40:22 AM EST

are some of us who don't care about silly pointless software politics.

[ Parent ]
Your Loss (3.85 / 7) (#38)
by yooden on Thu Nov 14, 2002 at 11:57:38 AM EST

Say I invest a lot of time and effort to learn the language and to write the Great Application. Just at this point the rules are changed and I'm no longer allowed to use K or to maintain my program or to run my program or to run my program outside the USA or to use an external editor or to bind to other languages or to use the optimized VM I wrote.

In what way is this pointless?

Just because you do not take an interest in politics doesn't mean politics won't take an interest in you.
--Pericles

[ Parent ]

Not only that (2.66 / 3) (#48)
by Work on Thu Nov 14, 2002 at 01:30:54 PM EST

You might also be attacked by CIA and aliens from pluto. Please put on your tin foil hat.

[ Parent ]
Nonsese (5.00 / 1) (#58)
by bodrius on Thu Nov 14, 2002 at 02:54:25 PM EST

Everyone knows there are no secret CIA bases in Pluto. They wouldn't survive the encounter with Planet X next year. That's why they sent their agents to train with the Zeta Reticulians themselves. Anyway, there's no need to worry until next year.

 
Freedom is the freedom to say 2+2=4, everything else follows...
[ Parent ]

You don't have to talk about Software (none / 0) (#87)
by yooden on Fri Nov 15, 2002 at 04:13:59 AM EST

You are free to tell us of some more things you think about at night.

[ Parent ]
it's pointless because it's low probability. (2.00 / 1) (#73)
by Shren on Thu Nov 14, 2002 at 06:40:43 PM EST

If you really feel that way, then you better go out of your way to avoid owning anything. After all, the government can take it away with eminent domain.

And you might as well not write any open source code untill the GPL's tested in court. I'd say the chances of the K guy letting you use his language freely are better than the GPL winning a court case if someone with real money decides to take it on.

[ Parent ]

GPLnixed=lowprobability (4.00 / 1) (#84)
by sugarkandimt on Thu Nov 14, 2002 at 11:15:38 PM EST

For starters, let me just say - everything is politics. You ignore that fact at your own peril. There's almost no chance of the GPL being shot down in court. There are too many businesses (and governments for that matter) that rely on GPL'd software. The economic impact would be massively negative - not to mention the shitstorm that would erupt from the various open and free software communities themselves. In other words, the GPL has a fair amount of "might", market and mindshare behind it, and as we've seen in the U.S. legal system, this is often all one needs to win a favorable ruling. If the U.S. is stupid enough to actually ban the GPL, it would most certainly have a negative impact on our economy, as well as cripple us in R&D - the brain drain vac is already clogged due to 9-11, so we can hardly afford to take another hit to our attractiveness as a place for foreign students and workers to settle down in. I know that I would be highly motivated to defeat any effort to in any way alter or ban the GPL. GPL'd software is just the smart way to go, if for no other reason than it has shown that it is a highly appealing license for a lot of people, and produces software that is oftentimes superior to its proprietary counterpart. People will gradually realize that betting the farm on proprietary solutions should be avoided at all costs, and that support through funding for GPL software is a smart alternative.

On a personal level, I like free and open software because of the spirit of sharing and community that is infused within a lot of the people involved with its development and usage. I like that there aren't some extremely rich men benefitting from my use directly by receiving my money so that they may spread lies - lies that they themselves are aware of - about free and open software. I like, if I'm able, not to have to put money into the pocket of propagandists like that (Note: the first corporate PR firms were started in the U.S by former government propagandists whose job it was to spread known lies about the enemy). I like that it lowers the bar for would be competitors in any number of business settings (e.g. The FX houses and the explosion of competitors that have sprung up in what once was a pretty closed industry). I like that the GPL it impowers me, rather than some extremely hierarchical corporation where profit is the sole drive for creation. I like that its free, and that I can make copies of it without being labelled a thief. I know that it works, because I use it, and I've followd its progression, and, IMHO, it's just getting started as a force of positive change.

[ Parent ]

Probability (none / 0) (#88)
by yooden on Fri Nov 15, 2002 at 05:10:14 AM EST

Even if the K guy loves the community, the chances for, say, C getting unfree are several orders of magnitude smaller than K staying unfree. So I do not assume it would went one way or another, I just have no compelling reason to risk it.

If it's almost sure that K will get free, why wait?

If I ever would buy or build a house, I would check whether any constructions near the site are planned. After that check, my house would stand a better chance of not falling prey to eminent domain than the one right next to the jammed Autobahn.

If the GPL would be as fragile as you implied, it would already be blown away. In case you didn't know: There is a Washington software company with quite some cash in their pockets.


[ Parent ]

yes (none / 0) (#89)
by jjayson on Fri Nov 15, 2002 at 05:16:28 AM EST

In case you didn't know: There is a Washington software company with quite some cash in their pockets.
Yeah, Microsoft. If they ever challenged the GPL in court I would put my money on them winning, too.
_______
Smile =)
* bt krav magas kitten THE FUCK UP
<bt> Eat Kung Jew, bitch.

[ Parent ]
Microsoft vs. GPL (4.00 / 1) (#91)
by yooden on Fri Nov 15, 2002 at 05:27:42 AM EST

Yeah, Microsoft. If they ever challenged the GPL in court I would put my money on them winning, too.

You are quite a gambler. They do not even put their own money on it, even though they have all the cash in the world and the gain would be huge.

[ Parent ]
Reason the GPL has never been tested (none / 0) (#92)
by pwhysall on Fri Nov 15, 2002 at 06:10:30 AM EST

Even IBM, who have even more lawyers than Microsoft, know that the reason the GPL has never been tested in court is that there isn't a legal beagle on the planet with the stupidity or the cojones to try it - let alone the money.

When IBM don't bother trying to work around the GPL, that's a clear signal that the probability of the GPL being legally sound is approaching 1.
--
Peter
K5 Editors
I'm going to wager that the story keeps getting dumped because it is a steaming pile of badly formatted fool-meme.
CheeseBurgerBrown
[ Parent ]

because it doesn't need to be 100% open (none / 0) (#46)
by jjayson on Thu Nov 14, 2002 at 01:08:53 PM EST

You have to look at the person behind the software. Arthur makes sure all the bugs get fixed. He makes sure your feature requests get done. He has shown no propensity for one day turning about and pulling the rug out from everybody by closing something off. His old development project, A+, is now an OpenSource project. I really don't see the scare scenario that you describe in your other post. If none of that is going to happen, then what difference does it make, either K is good enough for your task or it isn't.
_______
Smile =)
* bt krav magas kitten THE FUCK UP
<bt> Eat Kung Jew, bitch.

[ Parent ]
It sure does (none / 0) (#90)
by yooden on Fri Nov 15, 2002 at 05:18:46 AM EST

I can live with unfree software in certain cases, because I could always ditch it for something else. However, I won't get back the resources I spent on learning it. These resources are a much larger factor for a programming language, so I won't spend them if the investment is not as secure as possible.

If nothing bad is going to happen, nothing bad is going to happen, but that can only be said in hindsight. Until then, a Free license is the best way to show that nothing bad will happen. If K is as good as Free, why not make it Free?

I repeat my initial request: Please do another article once K gets Free.

My horror scenario is a response to another comment. I only wanted to demonstrate why political issues can become important here. I have no reasons to believe that Arthur (if that's his name) even thinks about anything like that, and I commend him for the efforts he spend without compensation.
I should have make that clearer, sorry.

[ Parent ]

Sounds like... (4.00 / 1) (#27)
by IPFreely on Thu Nov 14, 2002 at 08:29:18 AM EST

it didn't have continuations, I didn't see any objects, it had too many operators, it didn't have a large community around it, it was strange and different, and it looked like line noise,

From all of that, I thought he was talking about APL. Continuations? Who needs 'em. you can write a whole program on one line. Line Noise? It has its own character set, it doesn't use the normal ASCII characters. Objects? No, it uses Vectors and Matrices. Too many Operators? Plenty of them!

I actually liked APL for a while. It was special purpose, but it was very powerful in that purpose.

functional programming (3.00 / 4) (#28)
by ueluei on Thu Nov 14, 2002 at 08:42:45 AM EST

I prefer languages as Haskell. The syntaxis can be very compact while the language is beautiful.

speed (none / 0) (#119)
by jovlinger on Fri Nov 15, 2002 at 07:32:59 PM EST

back in the day,

haskell was a beautiful language, but it was a memory hog, slow, and was very hard to predict why. The strictness analyser sometimes needed a little help, such as the cunning forcing of a value, to keep the stack from blowing up on numerical apps.

How is it these days?

[ Parent ]

minor nit (3.00 / 1) (#29)
by karb on Thu Nov 14, 2002 at 09:15:42 AM EST

I think it's "turing tar-pit" not "turning tarpit". Incidentally, it didn't know what either was until I checked out the venerable jargon file.

Excellent article, as well. Thank you.
--
Who is the geek who would risk his neck for his brother geek?

Wow (5.00 / 4) (#31)
by p3d0 on Thu Nov 14, 2002 at 10:59:43 AM EST

I must say, that primality test is very cool, if not very efficient.

This is one thing that bothers me a bit about functional languages: it's hard to tell what is efficient without fully and completely comprehending what is going on. In procedural programs, you can look for loops and procedure calls, and there can be reasonable code snippets that have neither. Furthermore, simple loops (without breaks/continues) can also be understood from an efficiency point of view.

FP and OOP both spoil this, because there aren't many realistic snippets of code with no operators/virtual method calls, and these things are a brick wall when it comes to understanding performance. You simply must understand exactly what the invoked operator/method will do, and that greatly increases the amount of the program one must understand in order to evaluate a program's efficiency.

Since the programmer's mental capacity is the bottleneck in software development, anything that can reduce the programmer's mental load is helpful. Paradigms like FP and OOP reduce the mental load for algorithms and information hiding (respectively), but for performance, I haven't seen anything that beats the procedural paradigm.
--
Patrick Doyle
My comments do not reflect the opinions of my employer.

the K methodology for developing software (5.00 / 1) (#45)
by jjayson on Thu Nov 14, 2002 at 01:04:37 PM EST

just write the code and hope it is fast enough. if it is, then leave it alone. if not, figure out where your time is spent with the timing functionality in the interpreter and rewrite those code segments.  Most importantly is to just write the code first and then see what problems you may have.
_______
Smile =)
* bt krav magas kitten THE FUCK UP
<bt> Eat Kung Jew, bitch.

[ Parent ]
Always good advice. [nt] (none / 0) (#49)
by p3d0 on Thu Nov 14, 2002 at 01:42:40 PM EST


--
Patrick Doyle
My comments do not reflect the opinions of my employer.
[ Parent ]
maintainability more important than efficiency? (4.00 / 1) (#50)
by br14n on Thu Nov 14, 2002 at 01:51:43 PM EST

Very interesting article, thanks! I've always liked C because (rightly or wrongly) I believe myself to be closer to the metal when writing code in it. But lately I've been using Ruby, as it is relatively beautiful and easy, and although it doesn't accomplish the work as quickly, I've found it to be fast enough to get the job done and in far fewer lines of code. In general, will code maintainability become more and more important over efficiency? Maybe efficiency should simply be relegated to compilers/interpreters and humans should worry only about algorithms.

[ Parent ]
yes (none / 0) (#110)
by expostfacto on Fri Nov 15, 2002 at 04:01:40 PM EST

In general, will code maintainability become more and more important over efficiency?
it already did. "make it correct before making it fast" has been conventional wisdom for years.
--
Carnage Blender: over 50 million battles served
[ Parent ]
maintainability vs efficiency (none / 0) (#142)
by Robb on Sun Nov 17, 2002 at 01:24:12 PM EST

When there is a tradeoff to be made the it is almost always better to choose maintainability over efficiency unless your back is really to the wall performance wise. (which is very rarely the case)

However, in my experience a good design is usually both efficient and maintainable. So, if you are always trading one for the other you might consider that maybe you (or whoever did the design) don't understand the problem as well as you should. This happens a lot when one group does the design and then hands it off to a team to implement.

[ Parent ]

Maintainability is always more important (none / 0) (#162)
by p3d0 on Sun May 18, 2003 at 01:25:09 PM EST

If your software is maintainable, then it will be flexible enough to get the performance you need later on.

If your system is sufficiently flexible, then you can get anything else (including performance) without too much difficulty. However, try retrofitting a fast system to make it flexible...
--
Patrick Doyle
My comments do not reflect the opinions of my employer.
[ Parent ]

Premature optimization is the root of all evil (4.50 / 2) (#77)
by jefu on Thu Nov 14, 2002 at 07:45:41 PM EST

Or so, it is said, was said by those Gods of Computing : Tony Hoare, quoted by Don Knuth.

I'd rather have readable, maintainable code, and  - when needed - find ways to make it fast (amazing how often this can be automated or delegated to other languages) than fast code that I need to toss out the first time I find an error.  

I'm also privately convinced that functional programming is only temporarily slow - that one of these days (perhaps with xslt and xquery as impetuses (impeti?)) compilers will be developed to make FP as fast as procedural programming.    

The biggest problem with Haskell, for instance, is memory managment, and I suspect that  moving it up out of lower level functions has the potential to change things rather a lot. (No, I'm not a compiler person and I'm not likely to take this on.)

[ Parent ]

Agreed (none / 0) (#93)
by p3d0 on Fri Nov 15, 2002 at 07:49:25 AM EST

If we never get a language that has great abstractions and manifest efficiency, I'll take the abstractions, and do the work to achieve the efficiency. However, I think there are a number of false dichotomies in software these days, and abstraction-versus-efficiency is one of them. Joel's recent pronouncements notwithstanding, I think proper abstractions do not need to try to hide efficiency concerns.
--
Patrick Doyle
My comments do not reflect the opinions of my employer.
[ Parent ]
Great language, hope it gets opened (none / 0) (#33)
by WilliamTanksley on Thu Nov 14, 2002 at 11:30:18 AM EST

If K were open, I'd use it a lot. If someone were to write an approachable tutorial to K, I'd teach it to my friends. As things are, in order to learn K I first tried to learn APL (since my university library had a book on it), then learned J (the online books are decent, "J for C programmers" was especially helpful), then went on to learn K.

I love K. It's stunning, awesome. I like J, but it's so complex and so much less natural to use. But I'm almost convinced that I wouldn't have figured out K without first learning J. That's a waste. And that's why we need a good K tutorial.

K is the logical replacement for the spreadsheet.

-Billy


learning J first? (5.00 / 1) (#44)
by jjayson on Thu Nov 14, 2002 at 01:02:43 PM EST

J is a very touch language to learn. I have tried and am still trying. I seem to adapt to the smallness of K much better. I brain must not be big enough for J. I would recommend going to other way and learning K before J, acutally.

I will be taking this putting it on my website and continually imrpoving it. I will try to add more information about lists or maybe go through the J for C programmers tutorial and redo it in K. I have been reluctant at times since the next version of K is "imminent" and that will change quite a bit of the language.
_______
Smile =)
* bt krav magas kitten THE FUCK UP
<bt> Eat Kung Jew, bitch.

[ Parent ]

Thank you for writing this tutorial. (5.00 / 1) (#62)
by WilliamTanksley on Thu Nov 14, 2002 at 03:11:45 PM EST

Really, you're right -- J is FAR too complicated. But that's part of the sad thing; K is simple, but its tutorials are TOO simplistic. You can learn how to do utterly simple things in it (and it does them well), but if you want to do anything real... Well, you're pretty much on your own.

Even the stuff about booleans I wrote I only knew because it's standard stuff in J. Your answer (I assume that was you) was good, by the way. Thanks.

-Billy


[ Parent ]

k tutorials (none / 0) (#138)
by sa on Sun Nov 17, 2002 at 08:35:21 AM EST

hi billy

i agree that k needs a book.  help me retire and i'll write one.

sadly, everyone i know who both wants to write such a book and is capable of doing so is busy earning a living (with k).  there is some k activity in academia, but there too people would rather code.  (dennis shasha, who writes the math. games column for sci. amer. and "dr eco" for dobbs is a crack k-ist.)

as you know, conditions are similar on the joy front.  manfred's papers are brilliant, and joy is magnificent, but i'm not holding my breath waiting for a book.

[ Parent ]

You mentioned your website... (none / 0) (#63)
by WilliamTanksley on Thu Nov 14, 2002 at 03:14:28 PM EST

Where is your website? I wanna learn K better.

-Billy

[ Parent ]

Down right now, but... (none / 0) (#65)
by jjayson on Thu Nov 14, 2002 at 03:28:05 PM EST

I am working on putting things back up. I used to have a page with all the K links I could find (not too many of them really) and all the documents for learning K.  It will be back up in a couple weeks at
http://www.xcf.berkeley.edu/~nordwick/k
_______
Smile =)
* bt krav magas kitten THE FUCK UP
<bt> Eat Kung Jew, bitch.

[ Parent ]
website (none / 0) (#74)
by jefu on Thu Nov 14, 2002 at 07:28:41 PM EST

Perhaps you'll be kind enough to announce here on k5 when your website is back up, and when the upcoming ("the next version of K is "imminent" and that will change quite a bit of the language.") changes to the language are in place.

[ Parent ]
It will be in my diary... (none / 0) (#99)
by jjayson on Fri Nov 15, 2002 at 02:09:19 PM EST

maybe I will do a compartive evaluation of the new and old language to describe how computer languages change is drive by user interest, or something like that.
_______
Smile =)
* bt krav magas kitten THE FUCK UP
<bt> Eat Kung Jew, bitch.

[ Parent ]
J vs. Scheme and write-only languages (none / 0) (#132)
by booyeah451 on Sat Nov 16, 2002 at 10:10:21 PM EST

One teacher assigns J for the required Functional Programming class at my school. All the other teachers teach Scheme (LISP). I took the class with Scheme which I enjoyed. Even if you can bitch at all the parentheses in LISP, its a really powerful language and very clean.

I did a lot of reading on J and tried it out and I absolutely did not like it. It seems very crappy because you have all these symbols. Yes you can be more expressive in a shorter amount of space, but it seems like it would be hard to come back 2 weeks later and look at your own code and understand whats going on.

I have heard that J is a write-only language, and I guess that K is also a write-only language, because they look like the share a lot of the same philosophy. (And they are one letter apart =)



[ Parent ]
Amusing google result (4.00 / 1) (#36)
by jbm on Thu Nov 14, 2002 at 11:48:23 AM EST

Results

Note: I have used K from C foreign function calls. It has nice to have a small language work without any leaks or bugs popping up.

agreed (none / 0) (#43)
by jjayson on Thu Nov 14, 2002 at 12:59:00 PM EST

The K/C and K/Java are the only two foreign interfaces I have used, but i enjoyed their simplicity the most. I have a small brain so only having to learn about 6 function call instead of 200 was a very nice change. I wish other systems could be so simple.
_______
Smile =)
* bt krav magas kitten THE FUCK UP
<bt> Eat Kung Jew, bitch.

[ Parent ]
Oh, K! (5.00 / 3) (#40)
by jefu on Thu Nov 14, 2002 at 12:22:55 PM EST

APL was one of the first programming languages I actually got paid for using and I quite liked it. Once you got used to ("You never learn anything, you just get used to it.") the syntax and the odd character set, you could do array operations quickly and very easily.

There was a story (folklore?) that some folks at Honeywell or CDC or wherever had an apl interpreter that would compile the operators on the fly down to parallel/vectorized form (not hard to do when there are all those vectors flying around) and run the vectorized form, so people could interactively play with algorithms at supercomputer speeds. Very cool. Even if only folklore the fact that it is so clearly possible with APL makes it cool. Indeed, after some experiments with a Connection Machine, I was surprised that there was no APL* for the CM4.

I like languages tailored for specific purposes. I still keep a copy of snobol around (for some things its still unbeatable), as well as icon, aplus, prolog and so on. I dont have a copy of Cobol, but if the right problem calls, I may have to get one and install it.

I'll take a serious look at K, but there is already aplus for linux (uses the apl character set), a very good apl that I'm using for some kinds of problem, so until K is open and provides some nice advantages, I may just sit with aplus.

One minor nit - you define :
pyth:{_sqrt(x*x)+y*y}
clearly meaning :
sqrt ( x2 + y2) and I suspect that K groups to the right (as does apl) so that it works, but I'd also suggest that, even for many apl'ers :
pyth:{_sqrt (x*x)+(y*y) }
might be just that wee bit clearer, at the relatively minor cost of a pair of parens. But perhaps its just my enfeebled brain complaining again.

the point is... (5.00 / 1) (#72)
by Shren on Thu Nov 14, 2002 at 06:33:12 PM EST

the point is that if you leave even one additional character in the code, the K truncheon squad shows up and beats you with rubber truncheons.

[ Parent ]
parallel execution (none / 0) (#137)
by sa on Sun Nov 17, 2002 at 08:22:05 AM EST

would you rather get hit by a hundred bullets one at a time or all at once?


[ Parent ]
spaces in code... (none / 0) (#98)
by jjayson on Fri Nov 15, 2002 at 02:07:40 PM EST

I have a problem of never having any. I have just become used to the right-to-left grouping and my eyes immediately pick out the two multiplication operators happening and the resulting sqaure. This seems natural, too. If I were to write in C "sqrt(x*x+y*y)" people would be used to precendence rules and do the same gruoping in their head, too. It is just a new way to learn to group operations.

I should used more spaces in my code, though.
_______
Smile =)
* bt krav magas kitten THE FUCK UP
<bt> Eat Kung Jew, bitch.

[ Parent ]

100:1? Conditions, please? (4.00 / 1) (#68)
by pla on Thu Nov 14, 2002 at 04:35:54 PM EST

I find this hard to believe. Even C++, as bloated as it can sometimes get, still has a fairly close relation between its atomic statements and a corresponding sequence of assembly statements. Even with hand-coded assembly, getting better than 4:1 improvement (size-wise, of course) over C takes some serious effort.

Then again, I have to admit that the vast majority of programs I download weigh in the megabytes, whereas somehow my own code, even doing similar tasks, almost always comes in under 100k (and I even statically link my executables whenever possible, so that should *ADD* to their size).

Since you mention that they only have an *interpreter* available, do you mean to compare source-code sizes? In that case, I would agree the 100:1 claim sounds more reasonable, but only because most people do not write C in the unintelligible-but-valid shorthand C makes possible (check out some of the past obfuscated code contest winners, for an example of what I mean).


source code and more (none / 0) (#69)
by jjayson on Thu Nov 14, 2002 at 04:56:41 PM EST

I was comparing source code sizes in those approximate ratios. However, all of compiled KDB relational database comes it at 40K  (not including the 200K for the interpreter).
_______
Smile =)
* bt krav magas kitten THE FUCK UP
<bt> Eat Kung Jew, bitch.

[ Parent ]
Source code size (none / 0) (#95)
by ENOENT on Fri Nov 15, 2002 at 11:39:16 AM EST

Only an insane language designer would decide that minimal source code size should be the ruling consideration in making design choices. From what I have now seen of K, I would NEVER use it. I would rather be able to understand what a line of code is doing than be able to write a line of code with fewer keystrokes.

So nyah.


[ Parent ]
Insane - or genius... (none / 0) (#96)
by joto on Fri Nov 15, 2002 at 01:12:39 PM EST

There are definitely some advantages to a compact coding style. The most obvious is to simply be able to look at more code at once.

As an example, consider the following java code that is pretty typical of some work I recently did for controlling some embedded equipment in the sea:

public class SomeBackgroundWorker
extends SwingWorker {
  private Data result;
  private int _a;
  private String _b, errmsg = "";
  public SomeBackgroundWorker(int a, String b) {
    _a = a;
    _b = b;
  }
  public Object construct() {
    try {
     result =
      aRemoteObject.aTimeConsumingTask(_a, _b);
    } catch (SomeException e) {
      errmsg = "Something is wrong";
    } catch (AnotherException e) {
      errmsg = "Another thing is wrong";
    }
    return result;
  public void finished() {
    if ("".equals(errmsg)
      somePartOfGui.updateWith(result);
    else
      statusBar.write(errmsg);
  }
}

public class SomeBackgroundTaskDialog
extends SomeGenericDialogClass {
  ...
  public SomeBackgroundTaskDialog() {
    Button ok = new Button("OK");
    ok.addActionListener(new ActionListener() {
      public void actionPerformed(ActionEvent e) {
        if (checkParametersOkOrShowErrMsg()) {
          SomeBackgroundWorker worker
           = new SomeBackgroundWorker(getFoo(), getBar());
          worker.start();
          hide();
          dispose();
        }
      }
    });
    ...
  }
}

Maybe a genius would be able to refactor all of this into something more convenient (I didn't really bother, since I didn't need _that_ many workers, but I suspect it's really a limitation of Java that makes such simple code take over a page (a macro facility would be good)). And all it does is a remote background call.

On the other hand, if you are using a language that emphasizes compactness of code, while still being readable for the programmer aquainted with it, this example would be tolerable, because you could fit it in a few lines. I doubt K would really help me here, but I'd be interested to see an example if it's true.

Of course, in C++, this example would probably have been even more horrible, mostly because java threads are manageable, and SwingWorker is really cool. But even in Java, something tells me that it shouldn't really be this way.

[ Parent ]

code clarity (none / 0) (#123)
by werner on Sat Nov 16, 2002 at 06:45:10 AM EST

I agree there. For all the clarity using longer names brings, languages like C(++) and Java remove a good deal of this clarity by requiring a lot of unnecessary crap. Perl, K and even Ruby all tend toward line-noise. I think Guido van Rossum got it right when he designed Python's syntax - I've yet to see unreadable python code (excluding deliberately impenetrable lambdas). You don't find yourself writing lots of declerations before you get to the meat of the problem, and there's no messing around hunting for lost or mismatched brackets or deciphering cryptic symbols or syntax. hell, python even throws an error if you use "=", not "==" in an if statement.

[ Parent ]
You lack a perspective (none / 0) (#97)
by jjayson on Fri Nov 15, 2002 at 02:03:53 PM EST

I was like you at first. I loved Scheme and hated the ugliness of K. However, you begin to see absolute beauty in how the language is designed.

An "insane" language designer would then be people such as Dr. Iverson who designed APL, one of the older computer language that is still in use today. Larry Wall would then be called insane (and for the most part I agree, but not because of how small Perl code can be). Arthur Whitney has had a hand in designing a few languages by now and each interation seems to be getting better.

The only reason you say you cannot read it now is because you have no experience. The simple grammar and easily understood operators make it easy to learn. You surely cannot be saying just because K uses "|" and not the word "reverse" that you don't like it. As with any language, your first 30 minutes looking at it is intimidating, but it gets easier from experience.

Short code does not just from the having symbols instead of words. All the operators in K are designed to make solving problems easy and efficient. That also means letting you think at a higher level instead of being held in the details.

The compact code allows you to see more of it at once and not have to page through so much overheard or unnecessary cruft. Being able to stare at a single line of code of the screen and zone into it will be easier than paging throug routine after routine and having to chase the code through 3 files.

Regardless if you can't read it or you think the language is impenitrable, there is a point at which code density overpowers other concerns. What if I can replace 100 lines of C code with a sinle line of K? How about 500? Maybe 700? If I came to your project and could replace your 100,000 lines application with just a screenful of K, you would have to think differently. A single person can maintain, modify, and debug a screen of K. How many people would it take you to do the same with a 100,000 line project in another language?
_______
Smile =)
* bt krav magas kitten THE FUCK UP
<bt> Eat Kung Jew, bitch.

[ Parent ]

Perspective (5.00 / 1) (#108)
by ENOENT on Fri Nov 15, 2002 at 03:54:08 PM EST

My view on K comes from a few basic observations. First, the "easily understood operators", as presented in this article, are actually very difficult to define. Try, for example, to explain what the '!' operator does, without using words like "if" or "unless". (And I doubt that this brief introduction touched on the full range of meanings for the operators listed!)

Second, the compactness of the code is a red herring. If I wanted to make a library of C functions with names like a(), b(), c(), etc., and use those for all of my programming needs, my application source code could be NEARLY as compact as K, but it could still be more comprehensible because I would avoid using the same name for unrelated operations. If I wanted to forego using whitespace, I would expect that my C code could even be smaller than K code.

Third, K's syntax rules are much more complex than Scheme's. In Scheme, you never have to play a game of "find the operator".

Finally, in response to your assertion that K's operators let you think at a higher level: any language that has support for such basic operations as list manipulation and higher-order functions can do everything that K can do. You said you've looked at Scheme (my current favorite language), but have you seen the really elegant and wonderful features of Haskell?

There are some really cool features in K (like the K tree), but the syntax, along with the fetish for minimizing lines that causes utter monstrosities like the XML parse referenced elsewhere, make K a poor choice for people who have to debug and maintain code, especially in cases where collaboration is important.

So nyah.


[ Parent ]
The syntax is simple, just not compared to Scheme. (none / 0) (#131)
by jjayson on Sat Nov 16, 2002 at 08:26:13 PM EST

My view on K comes from a few basic observations. First, the "easily understood operators", as presented in this article, are actually very difficult to define. Try, for example, to explain what the '!' operator does, without using words like "if" or "unless". (And I doubt that this brief introduction touched on the full range of meanings for the operators listed!)
Yes, the K operators are slightly more complex than operators in other languages. You just have to learn to think a little differently. Try explaing what "+" does in C++ without using if.  K operators have two forms, monadic and dyadic, so it makes sense to seperate the difinition along those lines. I chose to explain "!" because that is one that has the most special cases. I chose to explain "&" because that has no special cases, in the either the monadic or diadic form.

Second, the compactness of the code is a red herring. If I wanted to make a library of C functions with names like a(), b(), c(), etc., and use those for all of my programming needs, my application source code could be NEARLY as compact as K, but it could still be more comprehensible because I would avoid using the same name for unrelated operations. If I wanted to forego using whitespace, I would expect that my C code could even be smaller than K code.
I have tried this and the answer was no. Just to get the semantic functionality requires alot of code to deal with memory issues, like allocation and destruction. To get the speed issues, you would need to make heavy use of the macro facility using some Aspect Oriented programming techniques. Sometimes I can't even write C code that is as fast as my K code.

Third, K's syntax rules are much more complex than Scheme's. In Scheme, you never have to play a game of "find the operator".
I never said they were simplier than Scheme. I said they were simplier than most commonly used languages. Scheme has the least syntax of any language I have learned. K has no need for baroque precedence rules, for example. Parsing K from right to left, you can parse it with an LL(3) grammar, I believe. Compare this to C++ where you need infinite lookahead to resolve some symbols.

Finally, in response to your assertion that K's operators let you think at a higher level: any language that has support for such basic operations as list manipulation and higher-order functions can do everything that K can do. You said you've looked at Scheme (my current favorite language), but have you seen the really elegant and wonderful features of Haskell?
Yes, any language that supports higher order functions and list operations will support some of what K has to offer. You could say that C++ could emulate K with some very elaborate functional objects. This argument can be made of any pair of language: the old addage is that any sufficiently complicated program implements Lisp. However all the work required to do that, and not do it nearly as well, quickly becomes an issue. And, no language has all the features that K has to offer. The true uniqueness doesn't just come in other areas of K, like the K-tree or GUI system or triggers or dependencies, it comes in its aggregation of features that make it very well suited to many tasks.

There are some really cool features in K (like the K tree), but the syntax, along with the fetish for minimizing lines that causes utter monstrosities like the XML parse referenced elsewhere, make K a poor choice for people who have to debug and maintain code, especially in cases where collaboration is important.
Code will always look foreign in the first day looking at it. You need experience to make that go away. It took me about 2 weeks before I was able to read other people's code without major problems. You shouldn't expect to pick up anything new in 30 minutes.



_______
Smile =)
* bt krav magas kitten THE FUCK UP
<bt> Eat Kung Jew, bitch.

[ Parent ]
syntax matters (none / 0) (#141)
by sa on Sun Nov 17, 2002 at 11:16:08 AM EST

good points, and i to some extent i share your opinions.

i've come to dislike operator overloading:  !x is enumeration if x is an integer atom, and the variables in x if x is a dictionary.  k4 dispenses with operator overloading.

i'm less averse to operator ambivalence, but still, i agree that without it k code would be slightly more readable to newcomers.  and again, in k4 ambivalence is present in just one of the three semantically equivalent supported dialects.

the determined k programmer can, of course, avoid both "conveniences":

  enum:!:
  vin:!:

  a:enum 10
  b:vin d

so much for overloading!

  flip:+:

  2+3
  c:flip m

so much for ambivalence!

[ Parent ]

error checking (none / 0) (#94)
by toadi on Fri Nov 15, 2002 at 08:27:29 AM EST

Probably you forgot to write errorhandling. I can write small programs to. But they get al lot bigger when I write the errorhandling.

[ Parent ]
Great Article (none / 0) (#85)
by mvsgeek on Fri Nov 15, 2002 at 02:13:49 AM EST

I'm not sure if I can find a use for the language but it was definately entertaining if only because of it's esotericism.
- mvsgeek
How well does it... (none / 0) (#101)
by steveftoth on Fri Nov 15, 2002 at 02:19:18 PM EST

How well does K integrate into the world of say Win32 applications?  Can you do everything that you could do with only C/C++ in K?  Mostly this is a problem of bindings, being able to call in and out of the C libs that Windows provides.

What about Unix?  

Is it good for graphical applications or more text based ones?  

Are there any comercial apps written in K besides the kdb?

kinda, yes, yes (none / 0) (#104)
by jjayson on Fri Nov 15, 2002 at 02:51:21 PM EST

How well does K integrate into the world of say Win32 applications?  Can you do everything that you could do with only C/C++ in K?  Mostly this is a problem of bindings, being able to call in and out of the C libs that Windows provides.

What about Unix?

Well, you can use the C-K interface to do anything you want (it is only about 6 function calls, so learning and using it is pretty simple). By using that people have been able to do all sorts of things, like tie into the cut-and-paste systems. The same interface exists for UNIX, too.

Is it good for graphical applications or more text based ones?
K has a very unique GUI system. You can do simple GUIs very easy and they intergrate seemlessly into K. The GUI system is so easy that most people opt to go the GUI route instead of the text-based route (this is the only language where I know this is the case).

Are there any comercial apps written in K besides the kdb?
There are some available for purchase. Since K grew out of the financial sector there are more big financial companies that use it for internal projects than anything else, for example Island ECN is currently implementing a K/KDB system for something to do with order procressing. There are also very large government projects that I am not aware of the details, except that they were very very large projects that required very very large performance (the word I heard was that they were classified).
_______
Smile =)
* bt krav magas kitten THE FUCK UP
<bt> Eat Kung Jew, bitch.

[ Parent ]
SO... (none / 0) (#109)
by steveftoth on Fri Nov 15, 2002 at 04:00:30 PM EST

you say that the GUI is unique, that's great, but could you write a native looking Win32 app or a native looking X app?

[ Parent ]
gui (none / 0) (#136)
by sa on Sun Nov 17, 2002 at 07:57:42 AM EST

we've written a gui for k in swing which preserves the basic semantics of the native k gui.

it's a project, but our work demonstrates that it is possible to get the standard windows look-and-feel for an application otherwise written entirely in k.

more than that, actually.

the native k gui is radically data-driven - there are no function-calls to manage the interface.

e.g.

  v:10 20 30
  `show$`v

edit the window v -> assign to v
assign to v -> update the window

suppose you want to have s be the sum of v.  there are two ways to do this:

  s:+/v
  v..t:"s:+/v"
  `show$`s

whenever v is assigned, v..t fires, recomputing s.  since s is on the screen, the display will update.  

alternatively:

  s..d:"+/v"
  `show$`s

s depends on v.  whenever v is assigned, s is marked invalid.  when s is next referenced, it will recompute according to s..d.  since s is on the screen, it is treated as "always referenced".  

the native k gui is mil-spec, but it is very very fast and has zero memory overhead:  

  m:10000000 _draw 0  / 10 million floats
  `show$`m

a k application is a system of variables, connected by (procedural) triggers and/or (non-procedural) dependencies, some of which are mapped to the screen.  in our swing gui, we've continued the tradition, without access to any of the k internals.  applications are written entirely in k, as though the native k gui has been replaced with something a little prettier.

if you're willing to forego k's display semantics, i see no reason why you couldn't strap any gui you want to k.  

[ Parent ]

Sweet Jesus, No! (5.00 / 1) (#102)
by egg troll on Fri Nov 15, 2002 at 02:24:40 PM EST

I hope to God that this and this are intenionally obfuscated pieces of K code. Otherwise, this language is even more hideous than Perl!

He's a bondage fan, a gastronome, a sensualist
Unparalleled for sinister lasciviousness.

sadly, no ;) (none / 0) (#103)
by jjayson on Fri Nov 15, 2002 at 02:41:32 PM EST

The XML parses is a 14 line DOM-style parser. The bottom half of the file is documentation using a mutiple comment (\). It was written by Arthur Whitney.

The XHTML is a 30 line DOM-style compliant parser written by somebody else, but based off the original XML parser. They are both in production use at the moment too, so they are proven to work. In the case of the XML parser it should work very well, too. It is incorporated into the KDB relational database system.

In the case of the XHTML parser you will notice that most of it is constant string data that makes it look so nasty. If you remove that, the code looks much better (but not by much).
_______
Smile =)
* bt krav magas kitten THE FUCK UP
<bt> Eat Kung Jew, bitch.

[ Parent ]

xhtml vs. xml (none / 0) (#135)
by E7L3 on Sun Nov 17, 2002 at 07:15:19 AM EST

I wrote the xhtml parser as a mixed mode extension of the original parser written by Arthur Whitney.

[ Parent ]
k people seem too proud of kdb (none / 0) (#105)
by expostfacto on Fri Nov 15, 2002 at 03:40:01 PM EST

maybe it's because it's the only "real" application done in K... it's just laughable to compare this with Oracle. comparison with gadfly (a python database) would be more apt.

as mysql has proven for many years, using a variant of sql with extremely limited isolation level support does not make you a RDBMS. as mysql has also proven, it does make you liable to make sweeping claims of speed for oversimplified queries. :/ this is right up there with monty claiming "real programmers don't need referential integrity":

The main reason [for kdb speed] is that kdb tables are "inverted", i.e. the data in each column is stored together, instead of in the row orientation used by most rdbms's. The column data is also organized for optimal processing speed. The result is an ultra high performance database.

the reason most databases store rows together is SQL is a ROW ORIENTED LANGUAGE. (duh?) so yeah, I imagine kdb is great for computing aggregates of a single column... but i strongly doubt it's faster than [insert real database of choice] in the general case. discussion of enterprise features like triggers, in-database procedural languages, views, etc. is noticably absent on the site.

i'm sure K is a great language, but knock if off with the ludicrous claims for kdb, please.
--
Carnage Blender: over 50 million battles served

quick and dirty relational semantics (none / 0) (#125)
by sa on Sat Nov 16, 2002 at 01:06:03 PM EST

actually, SQL is a *set* oriented language, with no implications for implementation.  kdb is fully compliant with the SQL92 standards, and in fact translates SQL92 into ksql, which is vector-oriented.  ksql is a true superset of SQL.

anyway, that is neither here nor there.  the claim that kdb outperforms the popular RDMSs can only be refuted by producing a (query,database) pair for which kdb does not outperform one of those systems.  i.e. find a counter-example to the claim.  a priori arguments alone do not refute.

for those who are interested in understanding how k works its magic, i've appended a script which implements the fundamental relational algebra in k.  no syntax, just the basic single-table operations restrict, project, group, and order.  the table t in the example is on the smallish side:  a million records (the number of fields is irrelevant to performance.)

kdb itself is much more efficient, but it is, as the paper claims, written in 100% pure loop-free k.

further examples can be found at www.nsl.com (click the herring).

to run the script, save it as t.k, download k, and say:

  k t

--

/ relational operations - sa 2002.11.16

table:{[f;n;m]@[_n;f;{n _draw y};m]}
t:table[`f`g`h`i`j;1000000;5 7 50 50 50]

restrict:{[t;i]@[t;_n;@[;i]]}
project:{[t;f]@[_n;f;:;t f]}

name:{[f;o]`$($o),"_",$f}

group:{[t;f;o]@[_n;k,name'[f;o];:;(+?+t k),o@''t[f;=+t k:(!t)_dvl f]]}
 avg:{(+/x)%#x}
 sum:+/
 count:#:

order:where:{[t;f;o]{x y z x}/[_n;o;t f]}
 desc:>:
 asc:<:

u:restrict[t;where[t;`h`i;(&7<;&10=)]]
v:restrict[u;order[u;`g`f;`desc`asc]]
w:project[t;`f`g`h`i]
x:group[w;`h`h`h`i;`count`sum`avg`sum]
y:restrict[x;order[x;`g`f;`desc`asc]]

`show$'`u`v`w`x`y;

\

table[f;n;m] constructs a table t of cardinality n with fields f
restrict[t;i] returns t restricted to rows i
project[t;f] returns t projected to fields f
group[t;f;o] returns t grouped by f, aggregates with operations o on remaining fields
where[t;f;o] returns indices of rows where o[1]f[1]& .. &o[n]f[n]
order[t;f;o] returns indices of rows sorted by o[1]f[1]&...&o[n]f[n]

[ Parent ]

relational operations (correction) (none / 0) (#126)
by sa on Sat Nov 16, 2002 at 01:14:53 PM EST

group is not correctly described.  should have been:

group[t;f;o] returns t with each f aggregated by the corresponding o, grouped by remaining fields.

i don't hate comments, but they hate me.


[ Parent ]

relational operations (faster, more) (none / 0) (#158)
by sa on Wed Nov 20, 2002 at 03:37:40 PM EST

this version chops group back down to a single line. i've added insert, update, and delete for completeness. even so, no one should confuse this pedagogical toy with industrial-strength kdb. i've made it available so that skeptics can peek under the hood and see that, yes, it is possible to achieve significant (i.e. order-of-magnitude+) performance advantages using an rdbms *written in an interpreted language*. -- / relational operations - sa 2002.11.18 table:{[f;n;m]@[_n;f;{n _draw y};m]} rows:{[t;i]@[t;_n;@[;i]]} cols:{[t;f;g]@[_n;f;:;t g]} group:{[t;k;f;o].+(k,{`$($x),"_",$y}'[o;f];t[k,f]{a[z][y]. x}[i t k]'((#k)#`last),o)} i:{[d](#?i;i:(?i)?/:i:(#:'u)_sv(u:?:'d)?/:'d)} a.count:{[d;n;i]@[&n;i;+;1]} a.sum:{[d;n;i]@[n#*0#d;i;+;d]} a.last:{[d;n;i]@[n#*0#d;i;:;d]} a.avg:{[d;n;i]a.sum[d;n;i]%a.count[d;n;i]} a.list:{[d;n;i]@[n#,();i;,;d]} order:where:{[t;f;o]{x y z x}/[_n;o;t f]} desc:>: asc:: insert:{[t;d]@[t;_n;,;d]} update:{[t;f;i;d].[t;(f;i);:;d]} delete:{[t;i]@[t;_n;_di[;i]]} \t t:table[`f`g`h`i`j;1000000;5 7 0 0 0] \t t:insert[t;(1 2 2 1;3 5 6 2;.1*!4;.2*!4;.3*!4)] \t u:rows[t;where[t;`f`g;(&2;&5=)]] \t v:rows[u;order[u;`g`f;`desc`asc]] \t w:group[t;`f`g;`h`h`h`i;`count`sum`avg`sum] \t x:rows[w;order[w;`g`f;`desc`asc]] `show$'`t`u`v`w`x; \ table[f;n;m] returns a table of cardinality n with cols f whose values are drawn from m insert[t;d] returns t with d appended update[t;f;i;d] returns t with cols f updated at i with d delete[t;i] returns t with rows i deleted rows[t;i] returns t restricted to rows i cols[t;f;g] returns t with cols g of t projected to f group[t;k;f;o] returns t with keys k and aggregations o[1]f[1] ... o[n]f[n] where[t;f;o] returns indices of rows where o[1]f[1] and ... and o[n]f[n] order[t;f;o] returns indices of rows sorted by o[1]f[1] within ... within o[n]f[n] 4 x slower: group:{[t;k;f;o]@[_n;k,name'[f;o];:;(+?+t k),o@''t[f;=+t k]]} name:{[f;o]`$($o),"_",$f} avg:{(+/x)%#x} sum:+/ count:#: list:(::)

[ Parent ]
oops (none / 0) (#159)
by sa on Wed Nov 20, 2002 at 03:39:49 PM EST

forgot to choose the plain-text option (now *that's* unreadable!)

this version chops group back down to a single line.

i've added insert, update, and delete for completeness.

even so, no one should confuse this pedagogical toy with industrial-strength kdb. i've made it available so that skeptics can peek under the hood and see that, yes, it is possible to achieve significant (i.e. order-of-magnitude+) performance advantages using an rdbms *written in an interpreted language*.

--

/ relational operations - sa 2002.11.18

table:{[f;n;m]@[_n;f;{n _draw y};m]}

rows:{[t;i]@[t;_n;@[;i]]}
cols:{[t;f;g]@[_n;f;:;t g]}

group:{[t;k;f;o].+(k,{`$($x),"_",$y}'[o;f];t[k,f]{a[z][y]. x}[i t k]'((#k)#`last),o)}
 i:{[d](#?i;i:(?i)?/:i:(#:'u)_sv(u:?:'d)?/:'d)}
 a.count:{[d;n;i]@[&n;i;+;1]}
 a.sum:{[d;n;i]@[n#*0#d;i;+;d]}
 a.last:{[d;n;i]@[n#*0#d;i;:;d]}
 a.avg:{[d;n;i]a.sum[d;n;i]%a.count[d;n;i]}
 a.list:{[d;n;i]@[n#,();i;,;d]}

order:where:{[t;f;o]{x y z x}/[_n;o;t f]}
 desc:>:
 asc:<:

insert:{[t;d]@[t;_n;,;d]}
update:{[t;f;i;d].[t;(f;i);:;d]}
delete:{[t;i]@[t;_n;_di[;i]]}

\t t:table[`f`g`h`i`j;1000000;5 7 0 0 0]
\t t:insert[t;(1 2 2 1;3 5 6 2;.1*!4;.2*!4;.3*!4)]
\t u:rows[t;where[t;`f`g;(&2<;&5=)]]
\t v:rows[u;order[u;`g`f;`desc`asc]]
\t w:group[t;`f`g;`h`h`h`i;`count`sum`avg`sum]
\t x:rows[w;order[w;`g`f;`desc`asc]]

`show$'`t`u`v`w`x;

\

table[f;n;m] returns a table of cardinality n with cols f whose values are drawn from m
insert[t;d] returns t with d appended
update[t;f;i;d] returns t with cols f updated at i with d
delete[t;i] returns t with rows i deleted
rows[t;i] returns t restricted to rows i
cols[t;f;g] returns t with cols g of t projected to f
group[t;k;f;o] returns t with keys k and aggregations o[1]f[1] ... o[n]f[n]
where[t;f;o] returns indices of rows where o[1]f[1] and ... and o[n]f[n]
order[t;f;o] returns indices of rows sorted by o[1]f[1] within ... within o[n]f[n]

4 x slower:

group:{[t;k;f;o]@[_n;k,name'[f;o];:;(+?+t k),o@''t[f;=+t k]]}
 name:{[f;o]`$($o),"_",$f}
 avg:{(+/x)%#x}
 sum:+/
 count:#:
 list:(::)


[ Parent ]

faster group by (none / 0) (#139)
by sa on Sun Nov 17, 2002 at 08:55:49 AM EST

this implementation of 'group by' is about 4 x faster than the original, and consumes significantly less memory.  sadly, the function has doubled in size, and the aggregators are correspondingly more complicated.  

i don't see any reason to keep calling 'restrict' and 'project' by their official names.  the first works on the rows, the second on the cols, so that's how i've named them.

to make things a little more interesting (and realistic), t in the example has integer "key" columns (f and g) and floating point "data" columns (h, i, and j).  technically, t isn't a relation, since it contains duplicate rows.

i've prefixed the execution lines with '\t', which gives timings in seconds.  group dominates, as you'd expect.

the final line -- `show$ -- puts the resulting tables on the screen.  and how satisfying they are to see.

have fun.

--

/ relational operations - sa 2002.11.17

table:{[f;n;m]@[_n;f;{n _draw y};m]}
t:table[`f`g`h`i`j;1000000;5 7 0 0 0]

rows:{[t;i]@[t;_n;@[;i]]}
cols:{[t;f]@[_n;f;:;t f]}

group:{[t;f;o]
 n:#?i:(#:'u)_sv(u:?:'t k)?/:'t k:(!t)_dvl f
 .+(k,name'[f;o];(((#k)#`last),o){x[n;i;y]}'t k,f)}

 name:{[f;o]`$($o),"_",$f}
 count:{[n;i;d]@[&n;i;+;1]}
 sum:{[n;i;d]@[n#*0#d;i;+;d]}
 last:{[n;i;d]@[n#*0#d;i;:;d]}
 avg:{[n;i;d]sum[n;i;d]%count[n;i;d]}

order:where:{[t;f;o]{x y z x}/[_n;o;t f]}
 desc:>:
 asc:<:

\t u:rows[t;where[t;`h`i;(&7<;&10=)]]
\t v:rows[u;order[u;`g`f;`desc`asc]]
\t w:cols[t;`f`g`h`i]
\t x:group[w;`h`h`h`i;`count`sum`avg`sum]
\t y:rows[x;order[x;`g`f;`desc`asc]]

`show$'`t`u`v`w`x`y;

\

table[f;n;m] returns a table of cardinality n with cols f whose values are drawn from m
rows[t;i] returns rows i of t
cols[t;f] returns cols f of t
group[t;f;o] returns t with each f aggregated by the corresponding o, grouped by remaining cols
where[t;f;o] returns indices of rows where o[1]f[1]& .. &o[n]f[n]
order[t;f;o] returns indices of rows sorted by o[1]f[1]&...&o[n]f[n]

4 x slower:

group:{[t;f;o]@[_n;k,name'[f;o];:;(+?+t k),o@''t[f;=+t k:(!t)_dvl f]]}
 name:{[f;o]`$($o),"_",$f}
 avg:{(+/x)%#x}
 sum:+/
 count:#:

[ Parent ]

think more, post less (none / 0) (#140)
by sa on Sun Nov 17, 2002 at 09:39:09 AM EST

good code, bad use:  changing t's data, i forgot to change the queries, giving empty results.

this seems to be correct:

/ relational operations - sa 2002.11.16

table:{[f;n;m]@[_n;f;{n _draw y};m]}

rows:{[t;i]@[t;_n;@[;i]]}
cols:{[t;f]@[_n;f;:;t f]}

group:{[t;f;o]
 n:#?i:(#:'u)_sv(u:?:'t k)?/:'t k:(!t)_dvl f
 .+(k,name'[f;o];(((#k)#`last),o){x[n;i;y]}'t k,f)}

 name:{[f;o]`$($o),"_",$f}
 count:{[n;i;d]@[&n;i;+;1]}
 sum:{[n;i;d]@[n#*0#d;i;+;d]}
 last:{[n;i;d]@[n#*0#d;i;:;d]}
 avg:{[n;i;d]sum[n;i;d]%count[n;i;d]}

order:where:{[t;f;o]{x y z x}/[_n;o;t f]}
 desc:>:
 asc:<:

\t t:table[`f`g`h`i`j;1000000;5 7 0 0 0]
\t u:rows[t;where[t;`f`g;(&2<;&5=)]]
\t v:rows[u;order[u;`g`f;`desc`asc]]
\t w:cols[t;`f`g`h`i]
\t x:group[w;`h`h`h`i;`count`sum`avg`sum]
\t y:rows[x;order[x;`g`f;`desc`asc]]

`show$'`t`u`v`w`x`y;

\

table[f;n;m] returns a table of cardinality n with cols f whose values are drawn from m
rows[t;i] returns rows i of t
cols[t;f] returns cols f of t
group[t;f;o] returns t with each f aggregated by the corresponding o, grouped by remaining cols
where[t;f;o] returns indices of rows where o[1]f[1]& .. &o[n]f[n]
order[t;f;o] returns indices of rows sorted by o[1]f[1]&...&o[n]f[n]

4 x slower:

group:{[t;f;o]@[_n;k,name'[f;o];:;(+?+t k),o@''t[f;=+t k:(!t)_dvl f]]}
 name:{[f;o]`$($o),"_",$f}
 avg:{(+/x)%#x}
 sum:+/
 count:#:


[ Parent ]

KDB (5.00 / 2) (#130)
by jjayson on Sat Nov 16, 2002 at 08:04:32 PM EST

maybe it's because it's the only "real" application done in K... it's just laughable to compare this with Oracle. comparison with gadfly (a python database) would be more apt.
In the real-world this simply isn't true. K is used interally by top financial fund companies. KDB is used by some very large companies with alot of money to loose if they make bad decisions. KDB doesn't just back up a website at places like Oppenheimer, Fidelity, Lehman, Merril Lynch, Island ECN, and the US government. All these places could have chosen Oracle, but they didn't.

as mysql has proven for many years, using a variant of sql with extremely limited isolation level support does not make you a RDBMS. as mysql has also proven, it does make you liable to make sweeping claims of speed for oversimplified queries.
KDB is fully SQL92 compliant, with a stored procedure language, triggers, views, subselects, time-series, etc... What more could you want from it?

the reason most databases store rows together is SQL is a ROW ORIENTED LANGUAGE.
No. SQL is set oriented. It intentionally doesn't define an implementation. However, stop and think for a second. Most of the time when you do a select you are searching down a column to see what rows fit your needs, this naturally lends itself to a column-based implementation. The proof is in the numbers.

I imagine kdb is great for computing aggregates of a single column... but i strongly doubt it's faster than [insert real database of choice] in the general case.
How about the TPC and APB benchmarks: "Kdb handles much more than just SQL92 tables. Online analytical
processing (OLAP) on multi-dimensional arrays is done with our extended SQL language, KSQL. For example, on the 35 megabyte OLAP APB-1 benchmark queries, Kdb ran 12,000 queries per minute with no precalculation," and "it ran the gigabyte TPC-D (an industry standard decision support benchmark)
queries and updates on a 200MHZ PC with 64 megabytes of memory, an ultrawide SCSI
controller and four disk drives many times faster than the best published results." More specific numbers are avaible in the white-papers section of the website.

discussion of enterprise features like triggers, in-database procedural languages, views, etc. is noticably absent on the site.
It has all of those. Just read the documentation.
_______
Smile =)
* bt krav magas kitten THE FUCK UP
<bt> Eat Kung Jew, bitch.

[ Parent ]
reply (5.00 / 1) (#143)
by expostfacto on Sun Nov 17, 2002 at 06:00:04 PM EST

insert adds rows. update modifies rows. select returns groups of rows. seeing a pattern here? order by sorts... rows. "having" acts on groups of rows. etc.

sure, sql doesn't mandate how you store your data. but while saying "it's set oriented" is true, adding "... not row oriented" is manifestly not.

as to featureset, kdb does have views. my appologies. but neither the other features I mentioned, nor namespaces, nor ANSI standard joins (left/right outer, natural, ...) are mentioned in your reference manual. this last is pretty basic stuff in real applications. so if it does indeed support these features, you need to talk to the doc team because they're doing a pretty pathetic job.

btw, as I said in my first comment, a database w/o isolation levels isn't a real database in the ACID sense, and comparing TPC results from a db that doesn't support them with others that do is a joke.
--
Carnage Blender: over 50 million battles served
[ Parent ]

kdb (5.00 / 1) (#144)
by sa on Sun Nov 17, 2002 at 07:48:27 PM EST

kdb's namespace is the k tree.

kdb supports two query languages:  sql92, with all the forms of join; and ksql, in which joins are analyzed away.  kdb translates sql92 queries into ksql.

this is all covered in the reference manual, but as we all know, you really only get to know a language by using it.

table insert and update are easy to implement in k - if you wish to think of these as "row-oriented", that's fine:

  insert:{[t;d]@[t;_n;,;d]}
  update:{[t;f;i;d].[t;(f;i);:;d]}

the point of course is that these functions take tables (and other objects) as inputs and return tables as outputs.*

similarly, select does not return "groups of rows", but tables (although in SQL this is context-dependent, and anomalous).

since relations are sets, and sets have no order, sql's "order by" clause applies only to display.  the result of an "order by" is not a relation.  another SQL anomaly (though hardly the last).  one reason why ksql is so satisfying is that it eliminates these irrationalities and retrains (i would say: restores) our intuitions about tables.  if you really want to see into the heart of kdb, contrast and compare the SQL and ksql solutions (and theoretical performance) to the "uptick" problem:  given table t containing fields stock, time, quote, define an uptick as a quote for company x which is greater than the previous quote for that company.  

finally, your assertion that kdb can't possibly be a "real" database is no criticism at all - just name-calling.

* in k2, tables are dictionaries of equal-length vectors.  that's how they're implemented, and that's how they look to the programmer.  in k4, tables are lists of uniform records, where records are unit dictionaries.  that's how they look to the programmer, even though they continue to be implemented (internally) as dictionaries of equal length vectors.  in my opinion, it would be a mistake to say either that ksql is record-oriented or that it is column-oriented.  it is *table* oriented.

[ Parent ]

the uptick problem (none / 0) (#145)
by sa on Sun Nov 17, 2002 at 07:53:33 PM EST

that is, write a query against t whose result is a table containing all and only the upticks in t.

(k5 could use an editing facility.  some of us are just not very good proofreaders.)

[ Parent ]

"real databases" (none / 0) (#147)
by expostfacto on Sun Nov 17, 2002 at 11:56:55 PM EST

sorry to offend... but if you don't understand why acidity is a fundamental requirement for enterprise databases then you're really coming from a whole different world than that of mainstream db use.
--
Carnage Blender: over 50 million battles served
[ Parent ]
btw, re namespaces (5.00 / 1) (#148)
by expostfacto on Mon Nov 18, 2002 at 12:15:49 AM EST

aka schemas -- what that refers to is the ability to create objects (tables, procedures, ...) in different, separately permissionable areas, much like a unix directory structure. this appears to be another part of sql92 you don't support.

i have nothing against small database providers. it just bugs me when you make misleading statements about your featureset. especially when you start pulling total crap out like comparing tpc numbers on a non-acid db with real databases. as mysql is finding out, it's really easy to be fast when you don't bother with real isolation level support. it's harder to add that stuff in later when your customers outgrow your limitations.

oh, man. just found this gem:

As explained earlier, Kdb databases are files and directories on disk. This makes handling databases extremely easy because database files can be manipulated as operating system files. Backing up a Kdb database is implemented by using any standard file system backup utility. This is a key difference from traditional databases, which have their own back-up utilities and do not allow as direct access to the database files.
geez. someone who didn't know better would conclude that the cold-backup way is BETTER because it is "direct access." come on, guys. if you want to be taken seriously you can't write crap like this...

(i'll spell it out -- what if a transaction writes to file A, then file B, but your backup script reads B before it is written to? you've just backed up an inconsistent set of data. any backup scheme that requires reading from the FS is necessarily a cold-backup, i.e., requires the db to be off to guarantee correctness.)

(another thing -- I can't think of any database that doesn't allow FS-level access if you really want to do it that way. Oracle, Sybase, et. al. however do allow using raw partitions for speed. so again you're taking a feature you don't have and acting like it's GOOD you don't have it.)
--
Carnage Blender: over 50 million battles served
[ Parent ]

transaction logging (5.00 / 1) (#151)
by sa on Mon Nov 18, 2002 at 07:22:39 AM EST

database integrity is guaranteed since transactions are applied in memory and logged to disk atomically.  database inconsistency of the sort you describe is impossible in kdb.

you ask, "what if a transaction writes to file A, then file B".  but of course that never happens in kdb.  on disk, at any given time, you will find A, B, and the transaction log L, a list of transactions against A and B in the order received.  (remember:  kdb transaction rates are extremely high:  on the order of tens of millions per second.)

concentrating your attention on snippets of text from the manual may be edifying from the point of view of literary criticism, but will intefere with your understanding of how kdb solves the standard problems arising in a production environment.  

i think that's probably my final reply to you on these matters.  at this point, i'm afraid, you're on your own.

[ Parent ]

please (none / 0) (#153)
by expostfacto on Mon Nov 18, 2002 at 10:30:01 AM EST

disk writes aren't atomic. and if you're explicitly locking every file a transaction's going to touch before a write -- which is the only way to prevent an FS-based backup from being inconsistent -- you're going to kill concurrency so I assume that's not what you're doing. :/ yes, you can use a write-ahead-log to allow you to recover to a consistent state in the event of power loss, or what have you, but the fact is if you back up direct from the FS while your DB is running you ARE eventually going to back up an inconsistent copy.
--
Carnage Blender: over 50 million battles served
[ Parent ]
no, you don't get it. (none / 0) (#154)
by sa on Mon Nov 18, 2002 at 10:54:10 AM EST

suppose you create the db at time 0.  call what's on disk db0.  the transaction log is empty.

start the db:  read it into memory and apply the (empty) log.  (in this simple case, assume that the db fits in memory.  in practice, this is not required, but let's do the simple case first.)

so db in memory = db0, which is by definition consistent.

a transaction t comes in.  apply it to the db.

if it succeeds, log it to disk.  so now on disk we have db0 and a log with one transaction.  in memory we have t(db0), t applied to db0.  by definition, this is consistent, and so is what's on disk (since we haven't altered db0.)

continue applying and logging transactions as they arrive.  logging consists of a single atomic append to the log file.

suppose a transaction fails, leaving what's in memory inconsistent.  that's ok:  just read db0 into memory and apply the log up to that point.

at some point you want to checkpoint.  in another process, read db0 into memory and apply the log, then write the result out to disk as db1.  db1's transaction log is empty.

at some point, your gateway to the database can re-route queries to db1.

as i said, this is the simple case.  read the "high volume transaction processing" whitepaper cited above to understand how this method is generalized to databases > memory (splayed tables, parallel dbs).

[ Parent ]

every checkpoint requires writing a new copy? (none / 0) (#155)
by expostfacto on Mon Nov 18, 2002 at 12:30:52 PM EST

yes, that would keep it consistent, but it sure sounds like a big price to pay.
--
Carnage Blender: over 50 million battles served
[ Parent ]
checkpoint frequency (none / 0) (#156)
by sa on Mon Nov 18, 2002 at 03:43:11 PM EST

it may sound like a big price, but in practice it's negligable.

how frequently you checkpoint (if at all) is application dependent.  since checkpointing happens off-line, and doesn't involve the actively queried db, who cares how long it takes?  besides, disk i/o is plenty fast.

again, i recommend that you read that whitepaper.

[ Parent ]

kdb whitepapers (none / 0) (#152)
by sa on Mon Nov 18, 2002 at 10:28:51 AM EST

http://www.kx.com/product_info/technical_articles.htm

note especially the paper by whitney, shasha and apter, "high volume transaction processing".  if, after reading this, you still have questions, i'll be happy to take them up with you.

[ Parent ]

that is great thinking (none / 0) (#106)
by expostfacto on Fri Nov 15, 2002 at 03:48:03 PM EST

... but only when you are the only one who ever looks at your code.  when you are part of a team who each has his own "way to do it," perl is an absolute nightmare.

many, many years of research into SW engineering show that standards and conventions help keep you sane when working with others.  the fact that perl standardizes much less at the language level than most is a barrier to good practice, not an aid to it.

when it comes to the kitchen-sink school of language design, larry wall makes stroustroup look like an amateur.
--
Carnage Blender: over 50 million battles served

sorry (none / 0) (#107)
by expostfacto on Fri Nov 15, 2002 at 03:50:26 PM EST

this is my second post to K5... mis-read the UI. supposed to be a reply to this comment.
--
Carnage Blender: over 50 million battles served
[ Parent ]
My Confusion (none / 0) (#111)
by glassware on Fri Nov 15, 2002 at 04:12:09 PM EST

What is the argument for using more and more complicated operators? What is the argument for re-using the same operator in multiple conditions to mean different things? What is the argument for eliminating whitespace, and using a comment marker which is also an operator?

Perhaps the ! symbol means "produce a list of all the numbers from 0 to X". Perhaps it can be reused to mean different things in different cases. Why not give it a name that indicates what it means in each case? Would typing "factor(x)" instead of "!x" break your wrist or give you carpal tunnel?

Why are we trying to redefine the notion of what the symbol means in the first place? It takes time to learn what any symbol means. I applaud languages like Java that understand it is worthwhile to keep the syntax of other commonly used languages, even if they are not perfect, because it lessens the learning curve for new programmers. Yet, language developers seem to think that they can obtain a massive benefit by somehow discarding all their knowledge and starting over.

I have read some very well-written critiques of the microprocessor industry that speak along these same lines. Each company seems to think they can design a new microarchitecture that will be unique and compelling. After spending a huge sum of money, they build a CPU that does one specialized task really well, and requires programmers to relearn and rewrite everything. Is that really worth the investment they made?

As for K, I am not interested in learning languages that make code harder to read. Perhaps in the world you people live, code speed is 100% of your goal; but in my world, I produce volumes and volumes of code, none of which needs to be particularly fast. On a daily basis, I write a new program, read through an old program to effect a fix, and need to acquire knowledge of someone else's program.

As I see it, the prime usefulness of this K language is to prevent users from inserting comments into their code by stacking it so densely that explanations of the author's thought processes are wrung out. More power to you. I prefer to have a thoughtful comment every three lines of code, which in K seems to compress down to about two characters worth of "line noise".



syntactic compression and lexical density (none / 0) (#127)
by sa on Sat Nov 16, 2002 at 02:02:36 PM EST

k syntax is simple (not quite as simple as joy, but then, joy *has* no syntax!):

nouns:  1 2.3 "abc" ...
verbs:  + * - ...
adverbs:  / \ ' /: \: ':

verbs are either intransitive (x kicks) or transitive (x kicks y).

intransitive verbs take nouns and return nouns.

transitive verbs take nouns and return intransitive verbs (2+3 is 2+ applied to 3).

adverbs take verbs or nouns and return verb (kicks slowly is a kind of kicking, +/ is a kind of addition).

k is read left to right:

  2--+x+y

  2 minus negate flip x plus y

  2 minus (the result of) negate (the result of) flip (the result of) x plus y

ambivalence can be defined away easily:  just give the intransitive verbs keywords:

  negate:-:
  flip:-:

  2 - negate flip x + y

no performance penalty for this.

pure k is parsed by scanning the line and performing successive table-driven bindings (see www.nsl.com/kparse.htm).  

we like the brevity, the density, and the regularity for many reasons, not least of which is that it leads to the discovery of interesting computational identities.  

for example, if you look at my toy SQL script elsewhere on this thread you'll see that

  {x y z x}/

implements both multi-field table sorting and converging boolean selection.  who would've thought that these operations, superficially so different, are computationally identical?  (do you think oracle implements them in a single piece of code?)

is there a price to be paid?  yes, but it's not what you think.  teams of k programmers suffer no more than those who practice other languages from intra-group befuddlement, but then, we'd just as soon rip it up and rewrite it as tinker with Other Peoples' Code (just kidding).

the real problem is start-up time to learn k.  despite the simple syntax and tiny number of datatypes, it takes some time to leave loopy habits of thought behind.  but the effort, at least in my opinion, is amply rewarded.

[ Parent ]

hi (none / 0) (#128)
by jjayson on Sat Nov 16, 2002 at 07:10:54 PM EST

Are you Stevan Apter? Where did you come from and how did you find this write-up? I still haven't told the K list or Andrei about it.
_______
Smile =)
* bt krav magas kitten THE FUCK UP
<bt> Eat Kung Jew, bitch.

[ Parent ]
the little things (none / 0) (#129)
by jjayson on Sat Nov 16, 2002 at 07:45:14 PM EST

Perhaps the ! symbol means "produce a list of all the numbers from 0 to X". Perhaps it can be reused to mean different things in different cases. Why not give it a name that indicates what it means in each case? Would typing "factor(x)" instead of "!x" break your wrist or give you carpal tunnel?
Why not have everything like Lisp in all languages? Why does C have + and not use a pseudo-function called add(x,y)? Because after a while you no longer need the extra verbosity. After reading K for about a month you become very used reading "!" as "ennumerate" and it becomes automatic. This really isn't an issue, just lack of experience. Addition is used so often that shortening it provides some benefit. In K the operators used most often are given operator status, and the rest are made into system functions.  The next version of K will bring more parity between those two, for now, different concepts.

Why are we trying to redefine the notion of what the symbol means in the first place? It takes time to learn what any symbol means. I applaud languages like Java that understand it is worthwhile to keep the syntax of other commonly used languages, even if they are not perfect, because it lessens the learning curve for new programmers. Yet, language developers seem to think that they can obtain a massive benefit by somehow discarding all their knowledge and starting over.
K doesn't come out of nowhere and redefine common notions. K is built from the experience of APL, and that has been for 20 more years than C. Also, a learning curve is only there at the beginning. K's syntax is very simple and easily learned, so coming from another language family, you will only experience growing pains for a couple weeks. A minor inconvenience.

As for K, I am not interested in learning languages that make code harder to read. Perhaps in the world you people live, code speed is 100% of your goal; but in my world, I produce volumes and volumes of code, none of which needs to be particularly fast. On a daily basis, I write a new program, read through an old program to effect a fix, and need to acquire knowledge of someone else's program.
K is best at optimizing developer time, I have found. It is also fast as a bonus most of the time. When it only takes a couple of lines of code, looking through it become much easier. If you can't fix the bug quickly, like you might not be able to do in many instances, you can rewrite half a line of code to get the desired functionality. You treat code density as if it is a bad thing. You assume that you will always have trouble reading K when in reality that fades with a little time.

As I see it, the prime usefulness of this K language is to prevent users from inserting comments into their code by stacking it so densely that explanations of the author's thought processes are wrung out. More power to you. I prefer to have a thoughtful comment every three lines of code, which in K seems to compress down to about two characters worth of "line noise".
But with two characters you don't need to explain much, do you. Nothing is stopping you from writing alot of comments. Write all you need. But I guarantee that as you learn to think at a higher level of abstraction that K provides you will find yourself needing to write fewer comments since you don't hang out in the lowest levels any more.
_______
Smile =)
* bt krav magas kitten THE FUCK UP
<bt> Eat Kung Jew, bitch.

[ Parent ]
Excel is a language???? (none / 0) (#133)
by ThreadSafe on Sun Nov 17, 2002 at 12:22:22 AM EST

aye?

Make a clone of me. And fucking listen to it! - Faik

questions (none / 0) (#134)
by Josh A on Sun Nov 17, 2002 at 05:42:56 AM EST

Is there more than one K mailing list? How do we join it/them?

Where can we find actual information about this language, as opposed to the non-information on the kx.com site?

Do you think if the source was opened up, we might have an [insert nonsupported OS, like OS X] version and an apache module to embed K in html pages anytime soon?

---
Thank God for Canada, if only because they annoy the Republicans so much. – Blarney


more links (none / 0) (#150)
by jjayson on Mon Nov 18, 2002 at 12:36:09 AM EST

More infomation on the K mailing list, plus some directories of test code is here:

http://www.kx.com/download/developer.htm

There is documentation here:

http://www.kx.com/download/documentation.htm

I used to have a webpage that aggregated some information, but I lost it and just started to try and rebuild it here:

http://www.xcf.berkeley.edu/~nordwick/k/

_______
Smile =)
* bt krav magas kitten THE FUCK UP
<bt> Eat Kung Jew, bitch.

[ Parent ]

where is the 'strictly-free' implementation? (none / 0) (#146)
by dawandg on Sun Nov 17, 2002 at 11:24:11 PM EST

Ok, so I'm just about (85-90%) convinced that this isn't a joke. And as it happens, I'm trying to spec out a project where this kind of speed would be very helpful.

But jjayson mentions a strictly free version, and I can't find it. Does anyone know where this is? Obviously I can start playing with the licensed version, but I don't want to commit unless I can be sure of the terms.

hmmm... (none / 0) (#149)
by jjayson on Mon Nov 18, 2002 at 12:29:18 AM EST

There is an interpreter available for you to distributed with you product. I don't know where it is, though. It may be something you get asked purchasing a license. If you are really serious, just call Kx and ask. They are a small company so it should be easy to get this information.
_______
Smile =)
* bt krav magas kitten THE FUCK UP
<bt> Eat Kung Jew, bitch.

[ Parent ]
A Shallow Introduction to the K Programming Language | 162 comments (156 topical, 6 editorial, 0 hidden)
Display: Sort:

kuro5hin.org

[XML]
All trademarks and copyrights on this page are owned by their respective companies. The Rest 2000 - Present Kuro5hin.org Inc.
See our legalese page for copyright policies. Please also read our Privacy Policy.
Kuro5hin.org is powered by Free Software, including Apache, Perl, and Linux, The Scoop Engine that runs this site is freely available, under the terms of the GPL.
Need some help? Email help@kuro5hin.org.
My heart's the long stairs.

Powered by Scoop create account | help/FAQ | mission | links | search | IRC | YOU choose the stories!