Paolo Amoroso's Journal

Tech projects, hobby programming, and geeky thoughts of Paolo Amoroso

My old blog post Why your blog still needs RSS was shared on Hacker News, made it to the home page with about 250 upvotes, and so far generated almost 9K views. I'm pleased as it hints there's still a lot of interest in RSS.

#blogging

Discuss... Email | Reply @amoroso@fosstodon.org

I integrated Femtounit, my Interlisp unit test framework, with the File Manager and the SEdit structure editor.

To achieve this I defined the new File Manager type TESTS for Femtounit tests and redefined DEFTEST in terms of it, then tweaked the code formatting of tests in SEdit. Now the system notices and keeps track of new and modified tests.

Here's the File Manager type menu, which SEdit pops up when opening a test, with the DEFTEST option highlighted under TESTS:

Interlisp File Manager menu with the Femtounit types.

Also, now SEdit handles and properly formats test definitions like this of a function SQUARE to compute the square of its argument:

SEdit editing a Femtounit unit test definition on Interlisp.

Implementing the new features was much easier than expected.

The traditional way of adding types to the File Manager, described in the Interlisp Reference Manual, involves writing a dozen functions for most of which it's not clear how they're supposed to work. Medley 1.0 added support for two easy to use File Manager type defining forms that replace all that, XCL:DEF-DEFINE-TYPE and XCL:DEFDEFINER. This code is all it took for Femtounit's new TESTS type:

(XCL:DEF-DEFINE-TYPE TESTS "Femtounit unit tests")

(XCL:DEFDEFINER (DEFTEST (:PROTOTYPE
                            (LAMBDA (NAME)
                              (AND (LITATOM NAME)
                                   `(DEFTEST ,NAME ("Arg List")
                                      "Body")))))
                TESTS
                (NAME PARAMETERS &BODY BODY)
   `(DEFINEQ (,NAME ,PARAMETERS
      (LET ((FTU.TEST.NAME (APPEND FTU.TEST.NAME (LIST ',NAME]
        ,@BODY))))

This additional tweak makes SEdit format and indent DEFTEST unit test definitions the same way as DEFUN function definitions in Common Lisp:

(SEDIT:DEF-LIST-FORMAT DEFTEST CL:DEFUN)

The simplified process is not discussed in the Interlisp Reference Manual, where I'd have expected, but in a more obscure source, the Medley 1.0 release notes from page 52 of the PDF document. My proactive reading of all the documentation paid off as it let me spot such crucial information and save a lot of work.

#femtounit #Interlisp #Lisp

Discuss... Email | Reply @amoroso@fosstodon.org

Today I attended the funeral service of my beloved mother who passed away peacefully two days ago.

I'm signing off a nearly continuous shift as a full time caregiver started almost 13 years ago. Over this long time I took care first of my father, then a sister of my mother, and finally my mother. The years of the pandemic were the most demanding and exhausting, constantly pushing me to the edge of burnout and forcing me to take some time off.

I assisted my dear family members until their very end to the best of my capabilities. Now I'm ready and eager to start a new life.

#personal

Discuss... Email | Reply @amoroso@fosstodon.org

Write.as, the blogging platform I use, lets me embed a YouTube video in a post by just inserting the URL in a blank line of the Makrdown source.

It's a valuable feature with a major drawback: YouTube embeds contain user tracking code by Google. I don't mind such trackers but my many privacy minded readers do.

As a workaround I could insert the trackerless code YouTube provides, but the design of the video player is not responsive and gets cropped on mobile screens. Write.as relies on Embed.ly for YouTube and other embeds and Embed.ly doesn't support trackerless embeds. I and others tried to bring the issue to the attention of the Write.as developer but not much happened.

Managing tracking and cookie consent is a hassle, so what to do? I just went ahead and replaced the half a dozen embeds of my blog with links to the corresponding videos on YouTube.

A nice side effect is the Blacklight privacy inspector now reports 0 trackers and cookies on my blog.

#blogging #Google

Discuss... Email | Reply @amoroso@fosstodon.org

I left Reddit and Twitter in early 2022 when I joined Mastodon.

It was a few months prior to the rumors Elon Musk might acquire Twitter and my decision had different motivations: I was invisible on the platform. As an average user, the algorithms made it impossible for me to be seen or have interactions.

As for Reddit I left for a combination of these reasons:

  • algorithmic feeds designed to arise strong, often negative emotions
  • snark and noise in the comments
  • ads
  • impenetrable moderation rules that make it difficult to figure why posts are rejected, even after reading the guidelines and FAQs cover to cover and reviewing past threads

The Reddit API restrictions of June of 2023, and the migration of many to the Fediverse, made me curious about federated and independent Reddit alternatives, particularly Lemmy. I joined the Lemmy.ml instance because it focuses on topics I'm interested in and values I share, plus it has a critical mass.

I've been on Lemmy for the past couple of weeks. In the first days my instance was slow and broken, then performance and stability improved substantially.

Although not polished as corporate platforms, which is a feature, Lemmy's design is functional and intuitive. Some features make Lemmy better than Reddit, such as the ability to expand and collapse posts in the feed to quickly browse them.

While there's a lot of activity around mainstream or popular topics, some Lemmy communities are pretty quiet.

I don't mind new or lesser known platforms as content quality and valuable interactions are what I'm after, which doesn't necessarily correlate with size. I'm making it a point to seed with content and discussions the communities I subscribe to, as well as comment on and interact with posts by others.

All I need now is to stick around and keep contributing.

#fediverse

Discuss... Email | Reply @amoroso@fosstodon.org

I'm writing another Interlisp program, Sysrama, an Interlisp documentation tool for presenting information on the Lisp objects of a program. It produces reports that list the types and signatures of functions, the fields of records, global variables, property lists, Executive commands, and more.

The way I reference the details of Lisp objects when coding gave me the idea for Sysrama.

I often forget the names and signatures of the functions or the names of the record fields I need. Browsing or looking up the code for referencing them is a source of friction.

Interlisp comes with the powerful program analysys tool Masterscope that gives its best with answering specific questions on the internals of programs. But it has a steep learning curve and it doesn't provide the kind of big picture view I seek. Instead, I wanted a simple tool for producing an overview of the main Lisp objects in a program.

This is a sample report Sysrama prints on another of my Interlisp programs, Stringscope:

Sample output of the Sysrama documentation tool for Interlisp.

The main sections group objects under the same File Manager types, such as FNS or RECORDS. This is because Sysrama can extract information only from programs under File Manager control.

Suppose you want to analyze the Lisp program MYPROG. Once Sysrama is in memory, load MYPROG:

(LOAD 'MYPROG)

To have Sysrama print a report with information on MYPROG evaluate:

(SUMMARIZE 'MYPROG)

You can narrow down the information to specific File Manager types such as FNS and RECORDS:

(SUMMARIZE 'MYPROG '(FNS RECORDS))

or to specific objects like the function MYFUN:

(SUMMARIZE 'MYPROG 'FNS 'MYFUN)

More documentation is available at the project repo.

Sysrama already does most of what I had in mind but I'll implement a few more features.

I'll tweak the reports to show more information on some Lisp objects. And I'll add the ability to redirect the output to a scrollable window rather than to the primary output stream. By default Interlisp windows don't save the output history and can't be scrolled back, so such a feature will help review reports that don't fit in a window.

#sysrama #Interlisp #Lisp

Discuss... Email | Reply @amoroso@fosstodon.org

Medley is a rich development environment but it's missing a test framework. Or so I thought. To fill the supposed gap I wrote Femtounit, a tiny — hence femto — unit test framework for Interlisp.

I wanted a small framework simple to port to or write for Interlisp, yet useful in practice. At less than a couple dozen lines of code, Femtounit took very little effort to design and write as it's based on the PCL test framework Peter Seibel described in Chapter 9 of his book Practical Common Lisp.

I reused much of Peter's design and code, adapting it to Interlisp and tweaking the reporting of tests. Femtounit outputs a single period character for every passed test, unlike the full report his framework prints.

Using Femtounit looks like this:

Usage of the Femtounit unit test framework for Interlisp.

Suppose you want to test this function that returns the square of its argument:

(DEFINEQ (SQUARE (X) (TIMES X X)))

You may define a TEST.SQUARE test function like this:

(DEFTEST TEST.SQUARE ()
  (CHECK.EXPECT (EQP (SQUARE 1) 1)
                (EQP (SQUARE 2) 4)
                (EQP (SQUARE 3) 9)
                (EQP (SQUARE 4) 16)))

To run the tests, just call the function:

(TEST.SQUARE)

which will print a period character for every passed test:

....

Some documentation is at the project repo.

After I finished the initial code of Femtounit, Larry Masinter pointed out Medley does have a test framework, and quite an advanced one. This system, which the Medley documentation simply calls test system and is much more than a framework, was originally designed to test Interlisp and its environment. The code is now in one of the Medley repos.

I thought I explored every nook and cranny of Medley and its documentation, yet I missed the test system. The system is interesting in itself and I'll use it for most of my code.

But Femtounit is a fun little learning project I still want to proceed with. It'll teach me how to integrate the framework with Interlisp for editing unit test definitions with the SEdit structure editor, as well as saving the definitions to files and managing them with the make-like File Manager tool.

#femtounit #Interlisp #Lisp

Discuss... Email | Reply @amoroso@fosstodon.org

Reading is the main use of my new Lenovo Tab M10 Plus 3rd Gen tablet, yet I hadn't checked out its reading mode. Now I did. Reading mode sets a color palette that's easy to the eyes such as black and white, systemwide or per app. Nice, but I can get a similar effect by changing the page color to sepia in Google Play Books and other reading apps.

#Android

Discuss... Email | Reply @amoroso@fosstodon.org

I'm back to work on Braincons, a Brainfuck implementation I'm developing with Medley Interlisp.

The new code I wrote implements the virtual machine (VM) and executes the Braunfuck instructions. Now Braincons can create and reset a VM, load a program into it, and execute the program until completion or for a designated number of steps.

The Lisp record BRC.VM represents the VM and holds the Brainfuck program, memory, machine state such as the instruction and memory pointers, and virtual I/O devices. All the functions that operate on the VM accept a BRC.VM record as an argument, update it as necessary, and return the record.

To decouple as much as possible I/O from other subsystems, BRC.VM contains the IN and OUT fields to hold a Lisp input stream and a Lisp output stream.

Any functions that need to read data or display output on behalf of the VM can do I/O to the relevant VM streams. This adds flexibility as most Interlisp text and window output functions accept streams as arguments.

Having the book A Philosophy of Software Design fresh in my mind after recently reading it, to design the Braincons VM I deliberately sat down to think about and write a specification of how the features needed to work. Although the book presents a lot of material I haven't absorbed yet, this preliminary work helped me design a relatively small and clean VM interface and saved some code rewriting.

Now that Braincons can parse, compile, and execute Braunfuck programs, the next step will be to build the user interface for editing and running programs, as well as inspecting the VM and its state.

#braincons #Interlisp #Lisp

Discuss... Email | Reply @amoroso@fosstodon.org

I bought a Lenovo Tab M10 Plus 3rd Gen 10.6” Android tablet to replace my old Lenovo Tab M8 HD 8” tablet. I picked this €189.00 Wi-Fi unit with 4 GB RAM and 128 GB storage:

Product box of Lenovo Tab M10 Plus 3rd Gen 10.6" Android tablet.

Motivation

The Tab M8 HD is on okay compact and light tablet with acceptable screen quality, but has a couple of issues that make it unsatisfactory for more than casual usage.

First, it's slow. Unbearably slow.

Every gesture or action comes with considerable lag. When the device boots up, it takes a lot of time to initialize and start all the processes before the system responds to user input. This is because of a combination of slow SoC and limited RAM, 2 GB for my Tab M8 HD. It's just not enough and the system is contantly swapping, with a major toll on latency.

Another issue is the 8” screen is not large enough to read wide, fixed layout documents and ebooks without workarounds.

I eventually got tired of the dog slow Tab M8 HD and its limitations and decided to replace it.

I wanted an affordable tablet with more RAM and noticeably better performance. In addition, I seeked a screen large enough to make A4 PDF documents, fixed layout ebooks, and programming ebooks with source code blocks comfortably readable, without adjusting the zoom or page settings of reading apps. Another important feature I was after is a software experience close to stock Android.

After overcoming some initial reservations about the weight and bulk of devices above 8”, I was eager to try a large tablet.

Reviews

My product research quickly homed in on the Tab M10 Plus 3rd Gen.

But at first something held me back, making me hesitate: the reviews were mixed, literally. Although the reviewers praised the design and finish, the great screen, and the price point, they expressed a wide spectrum of opinions over a feature I was very interested in, performance. Here are three representative reviews, from the most critical on performance (XDA Developers) to the most favorable (Android Police):

This range of opinions convinced me the performance of the Tab M10 Plus 3rd Gen was highly subjective. I deemed acceptable the risk of disappointment and went ahead with the purchase.

Hardware

I've been using the tablet for a few days and already love it. It finally comes with all I was looking for in such a device, adequate performance and screen real estate.

The design, material, and finish have a definitely premium look, especially at this price point. The screen is just gorgeous, bright enough and crisp. This is what the tablet looks like:

Lenovo Tab M10 Plus 3rd Gen 10.6" Android tablet.

Despite the size, the device feels less heavy than I expected and I can comfortably hold it for long sessions. Although I mostly use the tablet in portrait mode, the good balance and weight are making me use it more in landscape mode. The latter orientation is more natural than I thought and the large screen gives properly optimized apps enough room to take advantage of the additional area.

Performance doesn't disappoint. While the Tab M10 Plus 3rd Gen is no top of line device (why do reviewers pitch in benchmarks a budget tablet against a premium iPad, anyway?), it's way better and more responsive than the Tab M8 HD. Which is all I wanted. With the new tablet, lag is only occasional and with a short upper bound. I can finally pick up the device and use it right when the bootstrap ends.

Although most reviewers evaluate peformance by running demanding apps such as games or media editors, I actually mostly use reading apps like ebook readers, RSS feed readers, and web browsers. This may explain the subjectivity of opinions over performance.

For the kinds of apps I run, the tablet does really well. But it can handle more resource intensive processes such as 3D graphics simulations, for example the Celestia and GlobeViewer Moon astronomy apps.

Face unlock is usable, more responsive and accurate than the Tab M8 HD.

The cameras deliver barely serviceable results only with very good lighting, otherwise the slightest darkness produces a noisy mess. But the sensors are okay for the occasional video call or QR code scan.

Battery life is very good. A full charge gets me through at least three or four days of my typical usage.

Software

Lenovo delivers devices with mostly stock Android and little bloatware, which is among the reasons I went with the vendor.

The system software of the Tab M10 Plus 3rd Gen is indeed mostly stock Android 12 with a few extra apps for operating specific features, such as a notetaking app for the Lenovo Precision 2 pen or the Dolby Atmos options in the system settings. Android 13 is coming sometime in 2023.

I initially set up the home screen like this with the productivity, messaging, and astronomy apps I use most:

Home screen of Lenovo Tab M10 Plus 3rd Gen 10.6" Android tablet.

The reviews noted that, over the past few years, Lenovo dialed up the bloatware a bit. But, again, I accepted the risk. The tablet does come with some bloatware in the form of over a dozen preinstalled apps and games. But, to Lenovo's credit, all can be uninstalled, a one-time task of just a few minutes.

One more tweak is needed though. Tablet Center, a preinstalled Lenovo app that provides support and warranty information, issues occasional notifications promoting support plans. Turning off the app's notifcations removes this last annoyance.

Reading

The Tab M10 Plus 3rd Gen turned out to be perfect for the digital reading I do.

I tried several digital publications with a range of layouts and formatting. The default settings of the Google Play Books and Kindle apps are all it takes to comfortably fit A4 PDF documents and fixed layout ebooks on the screen, without zooming. The same goes with reflowable ebooks that contain wide source code blocks. Nearly all lines fit within the margins with no wrapping.

No reading settings adjustments are required, no workarounds.

The 10.6” screen of the device also helps with browsing websites and reading web content. The magic of responsive layouts nicely adapts the content and fills the large screen.

Conclusion

My experience with tablets began in 2012 with the original Nexus 7. After using other 7” and 8” tablets, the Tab M10 Plus 3rd Gen finally convinced me that, for the kind of reading-centered tasks I use these devices for, bigger is better.

The Tab M10 Plus 3rd Gen has all the features I wanted, exactly the way I wanted them. I nailed it.

#Android

Discuss... Email | Reply @amoroso@fosstodon.org

Enter your email to subscribe to updates.