On 16-08-2026 19:21, Zong wrote:
Hi Hans,
just curiosity, you've "removed the DUP() function from uBasic/4tH".
In your .bas-files examples in 4tH distri I count 381 dup()s and what
happens to the rosetta-code written in uBasic?
Hi Zong,
It's nice to see someone caring about uBasic/4tH! Usually people are
less interested in that program. So, let's start of with a "thank you"!
If I execute "grep -iF dup | wc -l", these are the numbers I get:
v3.64.3: 64 (this is a planned version)
v3.64.2: 63
v3.64.1: 197
v3.64.0: 137
You may have counted the instances instead of the lines, that's okay. 🙂
Anyways, if we observe the actual lines hit, you will see DUP() isn't
concerned at all.
As a matter of fact, most are due to UB-Forth programs -- you know,
where a Forth dialect is transpiled into uBasic/4tH BASIC.
You can view a complete list after the main article.
In short, ALL current "offical" uBasic/4tH programs are affected by this
change. Now -- it this change sudden? Err -- no. Take a look at the
uBasic/4tH section of v3.64.2. It says:
"Duplicate or retrieve argument sa. Returns a pointer to the du-
plicated or retrieved string. This function is deprecated and may
be removed in a future version."
And you know -- sometimes it's sooner, sometimes later, this is twelve
months later.
So -- why this long anyway? First of all, to see if my hypothesis is
true. I still add uBasic/4tH programs, also in Rosetta Code. So, if I
painted myself in a corner, chances are it will turn up. It hasn't.
Now what if it DOES turn up. Well, I understand the concept. DUP() was
created to introduce "quoted strings" to the string mechanism. And to
say the least, the resulting language wasn't a thing of beauty.
So I created a word that tested whether we had to deal with a quoted
string -- and if not, put back the token and continued. When you wrap
that in another word and use that word in most functions, the need for
DUP() greatly diminishes. Add to that the "walrus assignment" which
allows you to assign a string to a variable -- and that's it.
What do you need to do to restore DUP() functionality? 4 lines.
https://sourceforge.net/p/forth-4th/code/1811/
BTW, if you want to sign up to 4tH Google groups, go there and make a
post. You won't see it, but I see the post, I press the magical button
and viola -- not only your message appears, you also can post forever. I
see this happen regularly.
As far as Rosetta Code is concerned -- not all posts have strings. Now,
I won't chase 200 posts, but if I happen to come along one -- or if
someone makes me aware of an issue, I'll fix it. No trouble.
I hope this is satisfactory, if not lemme know!
Hans Bezemer
$ grep -iF dup *.bas
bullcows.bas:' digits 1 to 9, without duplication. The program should
ask for guesses to
cantor.bas:REM : done dup w < 0= ;
codebrk.bas:360 print "No zeros, no duplicate digits."
deldups.bas:' "Remove duplicate elements" for uBasic, J.L. Bezemer 2014
deldups.bas:' Given an Array, derive a sequence of elements in which all
duplicates are
deldups.bas:GoSub _RemoveDuplicates ' Now call the
subroutine to eliminate
deldups.bas: ' all the duplicates.
deldups.bas:_RemoveDuplicates ' Remove the
duplicates subroutine.
deldups.bas: For j = 0 To i-1 ' Look for a duplicate.
deldups.bas: If j+1 > i Then ' If found, delete
the duplicate.
f23match.bas:Rem : wins? dup 2 < dup ;
f23match.bas:Rem ." The number of matches is now " dup . cr
f23match.bas:Rem ." There are now " dup . ." matches remaining." cr
f23match.bas:Rem dup 5 <
f23match.bas:Rem nip dup 1-
f23match.bas:Rem cr ." My turn! I remove " dup . ." matches." cr -
fbench.bas:Rem : pprint dup format" ___# " type l dup if 1- else cr drop
4 then to l ;
fbench.bas:Rem i dup 2 / 2 do dup j mod 0= if 0 leave then loop dup
fchaotic.bas:Rem dup 2 < if
fchaotic.bas:Rem dup 1- QQ \ n Q(n-1)
fchaotic.bas:Rem dup \ ... n n
fguesses.bas:Rem dup \ check number
of guesses
figbench.bas:Rem 1+ dup 9999 >
figbench.bas:Rem 1+ dup dup / over
figbench.bas:Rem drop dup 9999 >
figbench.bas:Rem 1+ dup 2 / 3
figbench.bas:Rem * 4 + 5 - drop dup
figbench.bas:Rem 1+ dup 2 / 3
figbench.bas:Rem dup 9999 > until
figbench.bas:Rem 1+ dup 2 / 3 * 4 + 5 -
figbench.bas:Rem dup 9999 > until
figbench.bas:Rem 1+ dup 2 / 3 * 4 + 5 -
figbench.bas:Rem 5 0 do dup to @m(i) loop
figbench.bas:Rem dup 9999 > until
flander.bas:Rem dup ." Fuel (gal): " . cr over to a@ rot a@
flander.bas:Rem dup ." elocity (m/sec): " . cr rot
flander.bas:Rem dup ." Height (m): " . cr cr rot
flander.bas:Rem dup dup 0> if
flander.bas:Rem a dup 0 < dup if
flander.bas:Rem drop over over < dup
flander.bas:Rem a 0= dup if ." Have a nice day." cr abort then
fsinwav.bas:Rem 35 begin dup while SINE 1- loop drop
fsinwav.bas:Rem begin dup while cycle 1- loop cr drop
fstarfrt.bas:Rem : show dup 10 < if space then . ;
fstarfrt.bas:Rem over over percent + dup ." balance " .
fstarfrt.bas:Rem dup 2000 > if cr cr ." More than doubled in "
fthrow.bas:Rem dup char Q =
fusource.bas:REM s" " swap dup len 0
fusource.bas:REM dup i peek
fusource.bas:REM dup dup 96 >
fusqrt.bas:Rem dup if \ check for sqrt(0)
fusqrt.bas:Rem dup 10 rshift 1024 max
fusqrt.bas:Rem dup begin ( u x0 x1 )
fusqrt.bas:Rem dup 100001 <
fusqrt.bas:Rem dup 100 / format" ___#" type dup usqrt 4 spaces
format" ##.#" type cr
oll2bas.bas: If Comp(t, "DUP") = 0 Then Proc _Dup : Continue
oll2bas.bas:_Dup Write b, "Push Tos()" : Return
oll.bas:_HALT End ' below: ., DUP, NEGATE,
+, -, /, MOD,
oll.bas:_DUP Param (1) : Push a@, a@ : Return
tinyrpn.bas:' 67 dup * .
tinyrpn.bas:_quit end ' below: ., DUP,
NEGATE, +, -, /, MOD,
tinyrpn.bas:_dup param (1) : push a@, a@ : return
ubforth.bas: If Comp(t, "DUP") = 0 Then Proc _Dup : Continue
ubforth.bas:_Dup Proc _Output("Push Tos()") : Return