[vim/vim] Vim9 script truthiness issues (Issue #19173)

1 view
Skip to first unread message

Peter Kenny

unread,
2:32 PM (8 hours ago) 2:32 PM
to vim/vim, Subscribed
kennypete created an issue (vim/vim#19173)

I'm most of the way through updating the vim9.txt help, with only the last few subsections of Section 2 to go now, and have gotten stuck on this truthiness table in the "For the "??" operator" paragraph. It reads:

	type		truthy when ~
	bool		true, v:true or 1
	number		non-zero
	float		non-zero
	string		non-empty
	blob		non-empty
	list		non-empty (different from JavaScript)
	tuple		non-empty (different from JavaScript)
	dictionary	non-empty (different from JavaScript)
	func		when there is a function name
	special		true or v:true
	job			when not NULL
	channel		when not NULL
	class		when not NULL
	object		when not NULL (TODO: when isTrue() returns true)

The following types are all correct as documented: bool, number, float, string, blob, list, tuple, dictionary, func, job, and channel. Issues are with these:

  • class: "when not NULL" is incorrect because this type is never truthy. Trying to use a class to test for truthiness gives E1421: Class "Class" cannot be used as a value. The exception is null_class, though it is falsy anyhow (:vim9cmd echo null_class ?? 'falsy'). I think it should be removed from the list and moved to the notes covering the types that have no possible truthiness.
  • object: "when not NULL" is incorrect because it appears that, currently at least, all objects are falsy. So, this is either a documentation mistake requiring correction or its a bug. (Also, should, "(TODO: when isTrue() returns true)" be removed?)
  • special: This is not a type per se. There is the none type (v:t_none), which is falsy only, though. So, I think it would be better to remove special and instead include none in a note covering the types which have no possible truthiness.

For completeness, these should also either be included in the list or covered in my proposed note:

  • enum: This is the same as class, never truthy, gives E1421 (though without null_enum existing it is slightly different to class).
  • enumvalue: An enum value, whether initialised or not, is falsy. Whether that's intentional, and an initialised enum should be truthy, I don't know, though with it currently "never truthy", that aligns with the similar object type.
  • typealias: Gives E1421, so should just be added to the "never truthy" note.

Note/Particularly: There is a distinction between:

  • Types that can't be used as values at all (class, enum, typealias) ... E1421
  • Types where values are always falsy even when not null (object, enumvalue) ... are these special cases or a bug?

The following script illustrates these points.

vim9script

def Ftruthy(t: any, f: any): list<any>
    return [t, !t ?? 'truthy', f, f ?? 'falsy']
enddef

# These working as documented
# ---------------------------
echo 'Primitives, like number (type 0), work as documented:'
echo Ftruthy(9, 0)
echo '	'
echo 'Collections, like list (type 3), work as documented:'
echo Ftruthy([9], null_list)
echo '	'
echo 'Funcref (type 2) works as documented:'
var F = (x) => x
echo Ftruthy(F, null_function)
echo '	'
echo 'Job (type 8) works as documented:'
var Job = job_start(['echo', 'test'])
echo Ftruthy(Job, null_job)
Job = null_job

# Class and object
# ----------------
echo '	'
echo 'Class (type 12) gives E1421: '
class Class
    var x: number
endclass
try
    echo Ftruthy(Class, null_class)
catch
    echo v:exception  # E1421: Class "Class" cannot be used as a value
finally
    echo '	'
    echo 'Object (type 13) is never truthy, including when not null: '
    var o1 = Class.new(5)
    var o2 = null_object
    echo Ftruthy(o1, o2)
endtry

# Enum and enumvalue
# ------------------
echo '	'
echo 'Enum (type 15) gives E1421: '
enum Enum
    Placeholder
endenum
try
    echo Ftruthy(Enum, null_class)  # There is no null_enum...using null_class
catch
    echo v:exception  # E1421: Enum "Enum" cannot be used as a value
finally
    echo '	'
    echo 'Enum value (type 16) is never truthy, including when not null: '
    var e1 = Enum.Placeholder
    var e2: Enum  # uninitialized enum value == null (echo e2 == null ... true)
    echo Ftruthy(e1, e2)
endtry

And the output:
image.png (view on web)


Reply to this email directly, view it on GitHub.
You are receiving this because you are subscribed to this thread.Message ID: <vim/vim/issues/19173@github.com>

Reply all
Reply to author
Forward
0 new messages