Skip to Content
Author's profile photo Horst Keller

ABAP News for 7.40, SP08 – Logical Expressions

Predicative Method Calls

For quite some time the lack of a real boolean type in ABAP led to a lot of discussions inside and outside of SAP and especially in SCN. People kept asking, why can I not write

IF meth( … ).

  …

ENDIF.

The answer always was: Because you have to have a boolean type behind IF and no method can return a boolean type.

But in fact, the solution was absolutely simple and – tatarata! – is made availabe in Release 7.40, SP08.

You can write the so called predicative method call

… meth( ) …

as a short form of the relational expression

… meth( ) IS NOT INITIAL …

now and that’s already all! Of course,  methods that return a value of type ABAP_BOOL are especially suited for that purpose. We call those predicate methods now, but it’s not a prerequisite to use them.

So you can place simple functional method calls everywhere, where logical expressions are allowed: behind  IF, CHECK, ASSERT, COND, SWITCH, …

The documentation shows some examples:

IF cl_abap_demo_services=>is_production_system( ).

  cl_demo_output=>display(

     ‘This demo cannot be executed in a production system’ ).

  LEAVE PROGRAM.

ENDIF.

Here, a predicative method is called that returns ABAP_TRUE or ABAP_FALSE.

COND string( WHEN cl_demo_spfli=>get_spfli( to_upper( carrier ) )

               THEN `Filled`

               ELSE `Not filled` )

Here, a normal method is called and the result is true, if the table type return value contains lines.

Why didn’t we enable this long before?

New Boolean Function

Did you ever stumble over that one?

IF boolc( 1 = 2 ) = abap_false.
  cl_demo_output=>display_text( ‘yes’ ).
ELSE.
  cl_demo_output=>display_text( ‘no’ ).
ENDIF.

The relational expression boolc( 1 = 2 ) = abap_false is false! Why? Because boolc despite its name does not return c but string and the comparison rules for c and string blah, blah, blah

Now, with Release 7.40, SP08, we have an new Boolean function.

IF xsdbool( 1 = 2 ) = abap_false.

  cl_demo_output=>display_text( ‘yes’ ).

ELSE.

  cl_demo_output=>display_text( ‘no’ ).

ENDIF.

The relational expression xsdbool( 1 = 2 ) = abap_false is true, because xsdbool returns type XSDBOOLEAN from the ABAP Dictionary that is – yes, you guess it –  c of length 1. For the experts among you, XSDBOOLEAN is normally used for special mappings in XML-transformations and was reused here for quite another purpose. And that’s were the funny name xsdbool comes from.

The new Boolean function xsdbool can be used everywhere, where comparisons with type c length 1 are needed, especially comparisons with type ABAP_BOOL.But be aware of the fact, that the space that is returned by xsdbool for a false expression is cut in many operand positions, e.g. if you want to convert it with a builtin function like translate.

Assigned Tags

      24 Comments
      You must be Logged on to comment or reply to a post.
      Author's profile photo Peter Inotai
      Peter Inotai

      xsdbool is xsdcool 😆

      Author's profile photo Nigel James
      Nigel James

      Can you please explain why ABAP cannot have a boolean type ?

      IF false.

        cl_demo_output=>display_text( 'yes' ).

      ELSE.

        cl_demo_output=>display_text( 'no' ).

      ENDIF.

      Author's profile photo Horst Keller
      Horst Keller
      Blog Post Author

      Historical reasons. When ABAP was created, nobody cared and now it is too late. No way to introduce a new boolean data type with a meaningful name in a downward compatible way 🙁 .

      Author's profile photo Jacques Nomssi Nzali
      Jacques Nomssi Nzali

      Hello Horst,

      why is this predicative logic is limited to functional method calls? Shouldn't it be possible to define any NOT INITIAL value as a logical TRUE in a logical expression position without downward compatibility problem?

      best regards,

      Jacques

      Author's profile photo Horst Keller
      Horst Keller
      Blog Post Author

      Exactly this is currently under discussion.

      Something like

      IF ( value ).

      or maybe

      IF bool( value ).

      You cannot simply write  only a value because of IF seltab.

      Cheers!

      Horst

      Author's profile photo Former Member
      Former Member

      I can't imagine dealing with all that backwards compatibility...the folks working on the ABAP compiler are heroes.

      Author's profile photo Paul Hardy
      Paul Hardy

      I had been using BOOLC all over the place and so was horrified that IF BOOLC( 1 = 2 ) = ABAP_FALSE would not be FALSE.

      I tried it in my system and BOOLC( 1 = 2) evaluated to FALSE which is the opposite behaviour to that which you describe above.

      I am on ECC 6.0 EHP5. Support stack 702 BASIS 13.

      Has the BOOLC problem been resolved via a support stack?

      Cheersy Cheers

      Pul

      Author's profile photo Horst Keller
      Horst Keller
      Blog Post Author

      Hi Paul,

      BOOLC( 1 = 2) evaluates to a string containing a blank of length 1. So far so good. But comparing ` ` with ' ' or ABAP_FALSE is false, since the text field is converted to string resulting in an empty string. I bet that's the same on your system. And that's the trap. You simply cannot compare  BOOLC( 1 = 2) with ABAP_FALSE, only with ABAP_TRUE.

      Horst

      Author's profile photo Former Member
      Former Member

      Hi,

      don't know if it's mentioned already somwhere, but on 702 SAPKB70211 compiler accepts boolc( ) as actual parameter to a formal parameter of type c, which results in case of false boolc( ) result in unassigned parameter:

      CLASS lcl_test_boolc DEFINITION CREATE PRIVATE.

        PUBLIC SECTION .

          CLASS-METHODS: get_instance

            RETURNING value(ro_test_boolc) TYPE REF TO lcl_test_boolc.

          METHODS: takeit

            IMPORTING value(if_boolc) TYPE c.

        PRIVATE SECTION .

          CLASS-DATA: so_instance TYPE REF TO lcl_test_boolc .

      ENDCLASS .

      CLASS lcl_test_boolc IMPLEMENTATION .

        METHOD get_instance .

          IF so_instance IS INITIAL .

            CREATE OBJECT so_instance .

          ENDIF .

          ro_test_boolc = so_instance .

        ENDMETHOD .

        METHOD takeit.

          BREAK-POINT .

          WRITE: / if_boolc.

          SET PARAMETER ID 'TEST' FIELD if_boolc .

        ENDMETHOD .

      ENDCLASS .

      START-OF-SELECTION .

        lcl_test_boolc=>get_instance( )->takeit(

          if_boolc = boolc( space IS NOT INITIAL )

        ).

      Edit in: Type XFELD takes it 😉

      cheers

      Janis

      Author's profile photo Paul Hardy
      Paul Hardy

      I tested that in my system, and passed in

      IF_BOOLC = ( 1 = 2 ).

      The result was ABAP_FALSE.

      In my geeric method for seeing if things are true I pass in the result of BOOLC and my importing parameter was ABAP_BOOL wich is type C length 1 so I am laughing.

      So that is quite a handy tip.....

      Author's profile photo Former Member
      Former Member

      I had some inexplicable "doubts" about boolc and only started using it couple of days ago as a handy way of inverting the booleans, where necessary, while passing them in to a routine to write out to user master SET/GET parameters. That routine had c type, since I couldn't figure out if there is a lasting agreement about the right length of the values those can take... Now my "paranoia" meter will be peaking 🙂

      Author's profile photo Horst Keller
      Horst Keller
      Blog Post Author

      compiler accepts boolc( ) as actual parameter to a formal parameter of type c

      That is a documented feature, of course 😉

      • A string function or a string expression can
      • be bound to any character-like typed input parameter in a method call.

      and

      The return value of a function or the result of a calculation expression, a
      constructor expression, or a table expression is converted, if
      necessary, to the type of the input parameter and passed.

      That should explain the behavior discussed here ...

      Author's profile photo Christian Guenter
      Christian Guenter

      Hi Paul,

      you can work around this problem with a predicate helper method which has a returning value of type abap_bool.

      Example:

      ....

      method: is_one_eq_two RETURNING value(r_one_eq_two) TYPE abap_bool.

      ....

      method is_one_eq_two.

           r_one_eq_two = BOOLC( 1 = 2 ).

      endmethod.

      if is_one_eq_two( ) = ABAP_FALSE.  "evaluates to true

      endif.

      Regards Christian

      Author's profile photo Horst Keller
      Horst Keller
      Blog Post Author

      As of Release 7.40 less expensive with

      IF CONV abap_bool( boolc( 1 = 2 ) ) = abap_false.

      Best

      Horst

      Author's profile photo Christian Guenter
      Christian Guenter

      and less readable 😉

      Author's profile photo Marc Cawood
      Marc Cawood

      Why does this not work?

      DATA force TYPE boolean value 'X'.
      IF force. " Won't compile

      If force were a method returning boolean it would work so why not for a literal?

       

       

      Author's profile photo Horst Keller
      Horst Keller
      Blog Post Author

      Unfortunately this syntax is prohibited by an obsolete variant.

      Author's profile photo Marc Cawood
      Marc Cawood

      Got another puzzle for you Horst which doesn't work though I would expect it to:

      INSERT y_mytable FROM VALUE y_mytable(
          field = 'foo'
      ).
      

      Also, I always believed '-' is false in a BOOLEAN (as the data element description says) but I recently read '-' is "undefined" and '' is the true false. Which is it?

      Author's profile photo Horst Keller
      Horst Keller
      Blog Post Author

      You want to use a host expression in Open SQL, but you use the wrong syntax. Host expressions are available with 7.50 and must be placed in brackets @( ). See the documentation.

      We don’t have real booleans in ABAP. There are a lot of different frameworks definining their own artificial booleans and those might differ.

      Author's profile photo Marc Cawood
      Marc Cawood

      The docu doesn’t cover this case. It shows this working:

      DATA(ls) = VALUE y_mytable(
        field = ‘foo’
      ).
      INSERT y_mytable FROM  @ls.

      But an inline version does not compile:

      INSERT y_mytable FROM @(
      VALUE y_mytable(
      field = ‘foo’
      )
      ).
      Author's profile photo Horst Keller
      Horst Keller
      Blog Post Author

      What is your release?

      Author's profile photo Harald Wilde
      Harald Wilde

      Pfff. ABAP is getting uglier and uglier. Why pumping up that clean and straight language with tons of new statements that only developers missed that come from other languages to ABAB? Result: Destroying readness instead of simplifing it.

      Author's profile photo Horst Keller
      Horst Keller
      Blog Post Author

       

      Look at the examples in package SABAP_DEMOS_STRING_PROCESSING.

      Author's profile photo Harald Wilde
      Harald Wilde

      Well.. Thx for your answer, but it doesn't make me happy. I read the examples with interest. As you can see with that examples: The result ist always the same (writing a html-file). I am able to read quickly the 7.0 example, for the 7.4 example i need one hour to watch out and understand the new way of writing the same result. Using more and more implicit way of expressing, more and more brackets/symbols like ( } | &, more and more ways of expressing the same in another way. For me it doesnt increase readability. It just increases complexity of the language. I'am an old ABAP dinosaur... and not a fan of function-oriented languages. But thats the trendy line, i will adopt that.