Hacker News new | past | comments | ask | show | jobs | submit login
Byte Magazine – Smalltalk (1981) (archive.org)
123 points by tosh on May 27, 2019 | hide | past | favorite | 42 comments



I’m always amused that this is called a magazine. At least this particular issue. It’s nearly 500 pages long!!

My favorite chapter in the tome is the one by Peter Deutsch on control structures. Starts on page 322. I did Smalltalk for 20 years. I don’t have right words to express how much I loved the Smalltalk block closure, the fact that it was a reified object type that you could extend and use polymorphically is one of the unsung geniuses in Smalltalk. Every time I use python lambdas or Swift’s closures or Kotlin’s closures (the three closure enabled languages I use most today), I just sigh and wish.


I’m always amused that this is called a magazine. At least this particular issue. It’s nearly 500 pages long!!

Those magazine tended to be big, but Byte was at the top of its class. The only thing bigger I can remember was Computer Shopper, and that was massive.


Byte magazine was like a paper github. People published everything including the source code for BITBLT. A scoundrel later patented BITBLT and sued Xerox! It wasn't difficult for Xerox defend against the fake patent since it was published in Byte.

One issue had the entire source code for the Star Trek game written in Basic.

This brings back memories.


Byte had a bit more content, computer shopper was mostly ads.


Indeed, it was pretty typical to have a subscription to Byte, but buy an issue of Computer Shopper just when it was time to get a new computer. That, or see if someone else already had a recent issue.


It was the place to mail order components too! If you were building a system back in those days, that was one of the better tomes to dig through to find deals. That was really the only good place to find competitive offerings of a VESA local bus video card and find venders who you could trust. Good times.


Computer Shopper actually had some pretty good columnists working for it. Also, in a lot of ways at that time in the industry, the ads were great content.


I believe Ruby's blocks are based on Smalltalk's blocks. Could you describe how Ruby's blocks might be lacking in comparison to Smalltalk's?


In Smalltalk, blocks are actual objects in the system like everything else. You can send messages to them (I don't think Ruby allows this). In fact, that's the only way to get something out of a block -- send it the message #value (without args) or #value: (with args) to get some response back.

As the poster above you mentioned, you can then create your own objects that are polymorphic to this pattern if you need to. In other words, make your own object respond to the #value/#value: messages and other objects in the system that are, say, expecting a block can use your custom object all the same.

Objects that are polymorphic with blocks are often called "valuables" precisely because they respond to the #value messages.


> In Smalltalk, blocks are actual objects in the system like everything else. You can send messages to them (I don't think Ruby allows this).

Actually, blocks are Proc objects in Ruby:

  irb> def f(&b); b.call b.class; end; f {|x| "foo #{x}"}
  => "foo Proc"
> In other words, make your own object respond to the #value/#value: messages and other objects in the system that are, say, expecting a block can use your custom object all the same.

Are there not other messages that they might depend on that would also need to be implemented?

I'm having a hard-time thinking of a case where polymorphic blocks might be useful. Then again, I think Rack middleware (used in Rails for error handling and other things) are somewhat like what you're basically saying, since to define a middleware you mostly just need to define a `call` function. Yet, I'm not sure I'd consider this a block. Maybe the idea would be having the option to use simple blocks as middleware, but having the option to do something more complicated if one wants it.


> Are there not other messages that they might depend on that would also need to be implemented?

The answer to this is "maybe" but it doesn't really matter. You only need to implement the messages that will be sent by other objects and for "valuables" what we care about are the #value/#value: messages for the most part.

We can think of this as some kind of delayed evaluation. Perhaps we define an object who, when sent the #value message, goes off and fetches information from the net or something. We wait until the #value message is sent before doing so, just like we wait to evaluate a block until #value is sent.

An example of methods on Blocks that exist but probably don't need to be implemented for polymorphism are things like #fork and #forkAt which will run the block in it's own separate Process.


> The answer to this is "maybe" but it doesn't really matter. You only need to implement the messages that will be sent by other objects and for "valuables" what we care about are the #value/#value: messages for the most part.

If one is trying to pass a block-like object to a message that is expecting a block and which we cannot be easily sure is not dependent on other messages under obscure conditions, is it not easier to extend from / inherit whatever class the blocks in Smalltalk use (i.e. the equivalent of Proc in Ruby)? Or is it that documentation of such methods explicitly mention that they support not just Smalltalk blocks but also other "valuables"?

> An example of methods on Blocks that exist but probably don't need to be implemented for polymorphism are things like #fork and #forkAt which will run the block in it's own separate Process.

I mean, sure, you can intuitively guess that such messages might not be needed, but it might not always be such an easy thing to guess. Ruby Procs have the methods `arity` and `parameters` for example, which could be widely used to inspect the parameters accepted by a block to decide how to pass arguments in. I never used such methods, but it might be that methods from other libraries to which I pass these blocks could use them. I don't know.

I guess it could be a language culture thing. Dependence on only `#value` / `#value:` could be common convention in Smalltalk if usage of valuables is a more common idiom.


> If one is trying to pass a block-like object to a message that is expecting a block and which we cannot be easily sure is not dependent on other messages under obscure conditions, is it not easier to extend from / inherit whatever class the blocks in Smalltalk use (i.e. the equivalent of Proc in Ruby)?

For Smalltalkers this is just the difference between inheritance vs composition. Sometimes you don't want to directly inherit because your object's implementation of something like #value: is going to be quite different (ie, "mean" something different to the implementor -- but not necessarily the sender). By using composition over inheritance you avoid having to call the super's version, which would be something like:

  value: aParameter
    self doSomeInternalProcessingWith: aParameter.
    super value: aParameter.
  
> Or is it that documentation of such methods explicitly mention that they support not just Smalltalk blocks but also other "valuables"?

Yeah so you will see methods that look kind of like this:

  doSomethingWith: aValuable
      ^ self processStuff: aValuable value.
  
Here the variable name in the definition hints to the reader what it should be like (this is common in Smalltalk).

The "valuable" pattern-ish thing is not used super often as far as I've seen. Pharo uses it in composing Announcements and I think UI packages like the make use of it too.


First-class functions/closures are essentially polymorphic blocks. This is because, in the general case, a call through a first-class function might be followed by a dispatch step in which different blocks of code can be "selected" to run depending on runtime data.


Aha interesting!


To build on this, related to the theme of blocks: Smalltalk syntax is almost entirely free of magical constructs that you can't easily replicate in user code (off the top of my head `self`, `super`, the `[]` syntax for blocks, and compile-time literals can't be replicated), literally everything in Smalltalk is messages to objects (or method calls on objects in contemporary OO terms); thus a conditional which would be `if() { ... } else { ... }` in an Algol language is done by passing the `ifTrue:ifFalse:` message to a boolean object. Thus, if you need a custom control structure, you can implement them yourself and it'll be just like any other control structure in the language.


Seems like Functions being Objects in JavaScript gives you the same expressive power.


For sure!


Sort of accidentally, that's how it works in Java now.


It is the effect of the Internet of course. Magazines could (and did) publish articles that other magazines had covered and they they themselves had previously covered, which boosted the number of "editorial" pages, which gave them more pages for advertising. Most editors were sensitive to the ratio of editorial (content) to ads. That ratio indicated a level of "seriousness" to the content, if it was all content ("a true journal had no advertising and is bought for its cutting edge knowledge") to mostly ads ("an advertising vehicle with some grabby headline to get it into your hands.") Price was proportional to, from very expensive (journal subscription) to free (weekly advertiser).


>I loved the Smalltalk block closure, the fact that it was a reified object type that you could extend and use polymorphically

Some example of that?


Memoization. You could add a method to the class implementing blocks.

  Block>>memoize
    "Return a memoized one-argument block"
    | cache |
    cache := Map new.
    ^[:arg | cache at: arg ifAbsentPut: [self value: arg]]


  aBlock := [:foo | foo + 1].
  aBlockMemoized := aBlock memoize.


Byte Magazine had the best covers.

Page 98 has a fascinating Larry Tessler discussion of Smalltalk that includes a version of his "no modes" rant that later became the foundation of the Macintosh UX. It's fascinating to read in retrospect... he calls out Alan Kay's overlapping windows as de facto modes. (I'm trying to image a past where overlapping windows lost and tiled windows and virtual screens won.)

But the thing I like the most is the ability to write some code in the text editor, highlight it, and use the "do it" menu command to immediately execute it. Would be terrible for security... but I want it.


Somewhat to the side of your comment about "do it", but my experience of working in Smalltalk is that it's amazing.

The project I was working on had been in production sine 1996, and the Smalltalk VM it ran on dated to 1999 (Cincom bought VSE, license cost things happened), but the way Smalltalk lets you seamlessly move between writing code and exploring the state of a running system made the development process much smoother than any other system I've worked in. Also, the way (almost) everything in the VM can be extended or replaced was very useful in the context of very much legacy code in that project; there's a bug in the standard library? No problem, just patch the offending method(s) and ship the fix in the next release of the software.


>But the thing I like the most is the ability to write some code in the text editor, highlight it, and use the "do it" menu command to immediately execute it. Would be terrible for security... but I want it.

How would it "terrible for security"? It can be done in most text editors like Vim, Sublime, etc, it's just a menu command / shortcut away.


I think the idea is that end users would be able to do this in the running application, because the running application is just another Smalltalk image.


Agree about the covers. Also, as I'm flipping through the pages, I notice that the advertising copy is quite engaging. I wonder why today's typical paper magazine lacks that playfulness.


The ads were done by a lot of folks without an advertising background, and basically said what would attract them. I miss the lack of slickness, but I guess that only works in a hobbyist / early market.


> But the thing I like the most is the ability to write some code in the text editor, highlight it, and use the "do it" menu command to immediately execute it. Would be terrible for security... but I want it.

I don't see it as a security problem - just as accidentally headbutting your keyboard and spitting out "sudo rm -rf /" maybe a "security problem" in theory (to some), but not in practice!

Anyway, what you're looking for is the acme editor. Some great guides available online (the obligatory introduction is Russ Cox's video).

Ostensibly, its the "emacs for plan9", but has long since been available on other platforms, courtesy of plan9port (which makes much of the plan9 userspace available natively on unixy machines).

Acme has heavily inspired by the oberon (a full language-as-OS system, akin to lisp machines and what not) editing environment, and somewhat influenced by smalltalk (Rob Pike spent some early time at the Xerox Parc Labs playing with it).

It has the "text anywhere is executable (or searchable/plumbable/etc), if you want to" feature as a core concept.

If anyone is interested, along with a host of acme-like clones, there's a quite usable fork called [acme2k](https://github.com/karahobny/acme2k) which gives you a few additional keyboard shortcuts, plus the ability to apply your own colourscheme by editing a header file and recompiling (a la suckless and dwm).


>But the thing I like the most is the ability to write some code in the text editor, highlight it, and use the "do it" menu command to immediately execute it.

I vaguely remember reading (in an old BYTE issue, ha ha) that the Oberon operating system had something like this.


Plenty of text editors today allow this -- Emacs has "shell command on region" which many modes incorporate to allow running code fragments while editing. I'm not really seeing the security issue given that the code runs as you and can't do anything more than what you could do on the command line.


I used to think that too. Then I accidentally hit ctrl-shift-c in outlook webmail/chrome - opening the dev console rather than copying the highlighted text... Point being smalltalk did "win" in the end (or: so far).


Smalltalk is an amazing time sink if you can get past the syntax. Having learned about it with Squeak Smalltalk the first time during University, it immediately captured my mind. The great collection library, integrated ide, integrated version control, the absence of files. And most exciting everything you interact with comes with it's underlying code and can be changed at runtime.

Unfortunately trying to release a Smalltalk creation into production always turned out to be the most complex task. Smalltalk is an island. A beautiful island you can get lost in for years. But still an island.


> Unfortunately trying to release a Smalltalk creation into production always turned out to be the most complex task. Smalltalk is an island. A beautiful island you can get lost in for years. But still an island

This was always something which prevented me from really digging deeply into Smalltalk -- a nagging feeling that I was tossing bits into this VM, and eventually it'll work the way I want, but it's now bound forever into the particular VM and that I wouldn't even be able to get a code listing out. I'm sure I was over-dramatizing the challenges for myself, but I would really be interested to hear how you actually do get source code out and distribute it to others.


Smalltalk has had code versioning and sharing for a long time now (Envy, Monticello, etc). But in the past few years Git integration has really taken off. Pharo uses Iceberg to interact with git and the main image is now developed exclusively through it.


Look at the effort PARC Smalltalk people put into this Byte magazine issue, reaching out to the early microcomputer enthusiasts and industry.

Imagine if some of the more powerful early home computers (which often came with BASIC and nice intro-to-programming manuals) had come with Smalltalk instead, and the first generation of microcomputer whiz kids had started with that world of influences.

This Smalltalk issue of Byte was before my time, and I didn't get to use Smalltalk until a decade later. It was in a class taught by Bob Beck from Sequent, teaching OO as an adjunct on the side, using Smalltalk, C++, and object databases. This was one of the most influential classes I ever took. It also started my open source contribution habit, when I released my class project, a visual class hierarchy browser for Smalltalk. (A few years later, I actually had a chance to go work at PARC, in a junior role on a new project, and my overwhelmingly biggest regret in life was instead choosing to do something else that also seemed like something one had to go try or always wonder.)


I'm surprised modern SmallTalks (Pharo, Squeak) haven't yet explored optional types. (Yes, I know about StrongTalk. :-) )


You may (or may not?) find this interesting, by one of the cuis-smalltalk maintainers:

[LiveTyping](https://github.com/hernanwilkinson/LiveTyping) is a project which keeps track of types (and shows them to you) as they become known to the vm.

PS: cuis smalltalk = a less-bloaty "distribution" of squeak

(I say "distribution" rather than fork, as that more closely captures the spirit. Its just a thorough culling of the core classes, and stripping out of extraneous stuff - all running on the same squeak vm)


There are a couple of projects in the works that take an interesting approach to this.

Because the image/VM is always running you can essentially "turn on" a checker that will note which classes of objects have been sent as message arguments to some method. After a while you have more or less a list of "types" that a given method understands because of what the system has experienced. These can then be used for type hints in the IDE.

This approach is doubly interesting if you work with tests, because simply running a test suite you think is fairly comprehensive will result in a pretty good set of types.


Glorious - how I wish I’d kept mine!


In the early 1980's in addition to Smalltalk, the precursors of Haskell such as Hope, Miranda ... Byte would bring us these research languages and one would jump in and try them out.


This is the best BYTE issue. Good times.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: