Skip to content

No newline-free stdout write: display and print always terminate the line, so byte-exact stdout is impossible #704

Description

@logbie

Summary

Every WFL stdout write appends a newline. display and print both terminate the line, and there is no unterminated-write form — so a program cannot produce byte-exact stdout.

Reproduction

display "abc"
store printed as print of "def"

Command:

wfl g4_stdout_no_newline.wfl | od -c

Expected

Some documented way to write to stdout without a trailing newline — the shape of
write "abc" or a display ... without newline modifier.

No documentation citation exists — filed as a capability gap, not a broken
runtime. Docs/05-standard-library/core-module.md:7 documents display <value> as
the output primitive and never offers an unterminated form; nothing in Docs/
mentions suppressing the newline.

Actual

0000000   a   b   c  \n   d   e   f  \n
0000010

Exit code 0. Both writers append \n:

// src/stdlib/core.rs:7-17
pub fn native_print(args: Vec<Value>) -> Result<Value, RuntimeError> {
    ...
    crate::interpreter::io_capture::emit_line(&line);

display routes to the same emit_line. So print is not an
unterminated alternative to display — it differs only in argument handling.

File writes are unaffected and are byte-exact, which is worth stating because
it bounds the gap: writing a 3-byte payload abc with
write content payload into fout produces a file of exactly 3 bytes
(od -ca b c, offset 0000003, no \n). The gap is specific to stdout.

Environment

  • wfl --version: WebFirst Language (WFL) version 26.8.4
  • binary: system install C:\Program Files\wfl\bin\wfl.exe
  • commit: c277d8f
  • OS: Windows 11 Pro 10.0.26200
  • build: release

Also reproduces on the repo build (26.8.2). No .wflcfg in scope.

Context

Found while porting G:/repos/JShrink/src/JShrink/Minifier.php (a 738-line PHP
JavaScript minifier) to WFL. Minifier parity is byte-exact, so a forced trailing
newline changes the answer.

This one shaped the port's CLI contract: rather than emit to stdout like the
PHP tool, the port takes an output path argument and writes the minified result to
a file, and the parity harness diffs files instead of piping. That works and
nothing is stubbed — but it is a shape imposed by the language rather than chosen,
and any future WFL program meant to sit in a Unix pipeline will hit the same wall.

Lowest-priority item of the set: the workaround is clean and the blast radius is
limited to programs that must produce exact stdout.

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions